poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED] pickles: split elf pickle into elf-common, elf-32 and elf-64


From: Jose E. Marchesi
Subject: [COMMITTED] pickles: split elf pickle into elf-common, elf-32 and elf-64
Date: Tue, 21 Dec 2021 13:53:55 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

This commit splits elf.pk into three different pickles:

- elf-common.pk contains definitions that are common to both ELF32 and
  ELF64.
- elf-32.pk contains definitions for ELF32.
- elf-64.pk contains definitions for ELF64.
- elf.pk loads the files above.

2021-12-21  Jose E. Marchesi  <jemarch@gnu.org>

        * pickles/elf64.pk: New file.
        * pickles/elf32.pk: Likewise.
        * pickles/elf-common.pk: Likewise.
        * pickles/elf.pk: Move contents to elf-common.pk and elf64.pk and
        load these pickles.
        * pickles/Makefile.am (dist_pickles_DATA): Add elf-64.pk,
        elf-32.pk and elf-common.pk.
---
 ChangeLog             |  10 +
 pickles/Makefile.am   |   2 +-
 pickles/elf-32.pk     |  65 +++++
 pickles/elf-64.pk     | 454 ++++++++++++++++++++++++++++++++
 pickles/elf-common.pk | 311 ++++++++++++++++++++++
 pickles/elf.pk        | 707 +-------------------------------------------------
 6 files changed, 844 insertions(+), 705 deletions(-)
 create mode 100644 pickles/elf-32.pk
 create mode 100644 pickles/elf-64.pk
 create mode 100644 pickles/elf-common.pk

diff --git a/ChangeLog b/ChangeLog
index a35a2a06..ec72d83f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2021-12-21  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * pickles/elf64.pk: New file.
+       * pickles/elf32.pk: Likewise.
+       * pickles/elf-common.pk: Likewise.
+       * pickles/elf.pk: Move contents to elf-common.pk and elf64.pk and
+       load these pickles.
+       * pickles/Makefile.am (dist_pickles_DATA): Add elf-64.pk,
+       elf-32.pk and elf-common.pk.
+
 2021-12-21  Jose E. Marchesi  <jemarch@termi>
 
        * libpoke/pkl-gen.c (PKL_GEN_PUSH_SET_CONTEXT): Define.
diff --git a/pickles/Makefile.am b/pickles/Makefile.am
index 109ba1e4..35191032 100644
--- a/pickles/Makefile.am
+++ b/pickles/Makefile.am
@@ -1,5 +1,5 @@
 picklesdir = $(pkgdatadir)/pickles
-dist_pickles_DATA = elf.pk ctf.pk ctf-dump.pk leb128.pk \
+dist_pickles_DATA = elf-common.pk elf-64.pk elf-32.pk elf.pk ctf.pk 
ctf-dump.pk leb128.pk \
                     bpf.pk btf.pk btf-ext.pk btf-dump.pk bmp.pk \
                     color.pk rgb24.pk id3v1.pk \
                     dwarf.pk dwarf-common.pk dwarf-frame.pk dwarf-pubnames.pk \
diff --git a/pickles/elf-32.pk b/pickles/elf-32.pk
new file mode 100644
index 00000000..f6ff62ef
--- /dev/null
+++ b/pickles/elf-32.pk
@@ -0,0 +1,65 @@
+/* elf-32.pk - 32-bit ELF definitions.  */
+
+/* Copyright (C) 2019, 2020, 2021 Jose E. Marchesi.  */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+load "elf-common.pk";
+
+/* ELF32 basic types.  */
+
+type Elf32_Addr = offset<uint<32>,B>,
+     Elf32_Off = offset<uint<32>,B>;
+
+/* ELF32 relocation info.
+
+   r_sym is the symbol table index with respect to which the
+   relocation must be made.
+
+   r_type is the type of relocation to apply, which is
+   architecture-specific.  */
+
+type Elf32_RelInfo =
+  struct Elf_Word
+  {
+    uint<24> r_sym;
+    uint<8> r_type;
+  };
+
+/* ELF32 REL relocation entry. */
+
+type Elf32_Rel =
+  struct
+  {
+    Elf32_Addr r_offset;
+    Elf32_RelInfo r_info;
+  };
+
+/* ELF32 RELA relocation entry.
+
+   r_offset holds a section offset in relocatable files, a virtual
+   address in executable and shared object files.
+
+   r_addend holds a constant value to be added to the relocation's
+   value.  In architectures using Rel relocations this addend is
+   somehow stored in the relocation's memory location.  */
+
+type Elf32_Rela =
+  struct
+  {
+    Elf32_Addr r_offset;
+    Elf32_RelInfo r_info;
+    Elf_Sword r_addend;
+  };
diff --git a/pickles/elf-64.pk b/pickles/elf-64.pk
new file mode 100644
index 00000000..15763951
--- /dev/null
+++ b/pickles/elf-64.pk
@@ -0,0 +1,454 @@
+/* elf-64.pk - 64-bit ELF definitions.  */
+
+/* Copyright (C) 2019, 2020, 2021 Jose E. Marchesi.  */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+load "elf-common.pk";
+
+/* ELF64 basic types.  */
+
+type Elf64_Xword = uint<64>,
+     Elf64_Sxword = int<64>,
+     Elf64_Addr = offset<uint<64>,B>,
+     Elf64_Off = offset<uint<64>,B>;
+
+/* ELF64 relocation info.
+
+   r_sym is the symbol table index with respect to which the
+   relocation must be made.
+
+   r_type is the type of relocation to apply, which is
+   architecture-specific.  */
+
+type Elf64_RelInfo =
+  struct Elf64_Xword
+  {
+    uint<32> r_sym;
+    uint<32> r_type;
+  };
+
+/* ELF64 REL relocation entry.  */
+
+type Elf64_Rel =
+  struct
+  {
+    Elf64_Addr r_offset;
+    Elf64_RelInfo r_info;
+  };
+
+/* ELF64 RELA relocation entry.
+
+   r_offset holds a section offset in relocatable files, a virtual
+   address in executable and shared object files.
+
+   r_addend holds a constant value to be added to the relocation's
+   value.  In architectures using Rel relocations this addend is
+   somehow stored in the relocation's memory location.  */
+
+type Elf64_Rela =
+  struct
+  {
+    Elf64_Addr r_offset;
+    Elf64_RelInfo r_info;
+    Elf64_Sxword r_addend;
+  };
+
+/* ELF64 symbol.  */
+
+type Elf64_Sym =
+  struct
+  {
+    offset<Elf_Word,B> st_name;
+    struct uint<8>
+    {
+      uint<4> st_bind;
+      uint<4> st_type;
+
+      method _print = void:
+        {
+          printf ("#<stb:%s,stt:%s>",
+                  elf_stb_names[st_bind], elf_stt_names[st_type]);
+        }
+    } st_info;
+
+    struct uint<8>
+    {
+      uint<5>;
+      uint<3> st_visibility;
+
+      method _print = void:
+        {
+          print "#<stv:" + elf_stv_names[st_visibility] + ">";
+        }
+    } st_other;
+
+    Elf_Half st_shndx;
+    Elf64_Addr st_value;
+    Elf64_Xword st_size;
+  };
+
+/* ELF64 notes.  */
+
+type Elf64_Note =
+  struct
+  {
+    /* The first `namesz' bytes in `name' contain a NULL-terminated
+    character representation of the entry's owner or originator.  */
+    Elf64_Xword namesz;
+
+    /* The first `descsz' bytes in `desc' hold the note descriptor.
+    The ABI places no constraints on a descriptor's contents.  */
+    Elf64_Xword descsz;
+
+    byte[namesz] name;
+    byte[alignto (OFFSET, 8#B)];
+
+    byte[descsz] desc;
+    byte[alignto (OFFSET, 8#B)];
+  };
+
+/* Compressed section header, used in sections flagged with
+   SHF_COMPRESSED.  */
+
+type Elf64_Chdr =
+  struct
+  {
+    Elf_Word ch_type;
+    Elf_Word ch_reserved;
+    offset<Elf64_Xword,B> ch_size;
+    offset<Elf64_Xword,B> ch_addralign;
+  };
+
+/* The ELF64 dynamic section contents.  */
+
+type Elf64_Dyn =
+  struct
+  {
+    Elf64_Sxword d_tag;
+
+    union
+      {
+      /* Entries in the dynamic tags in a position >= DT_ENCODING
+         follow an uniform rule regarding what field is used for the
+         data: even entries use d_ptr while odd entries use d_val.  */
+
+        Elf64_Addr d_ptr
+          : (d_tag in [DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA,
+                       DT_SYMENT, DT_INIT, DT_FINI, DT_REL, DT_JMPREL,
+                       DT_INIT_ARRAY, DT_FINI_ARRAY]
+             || (d_tag >= DT_ENCODING && d_tag %2 != 0));
+
+        Elf64_Xword d_val;
+    } d_data;
+  };
+
+/* ELF64 section group.  */
+
+type Elf64_Group =
+  struct
+  {
+    Elf_Word flags;
+    Elf_Word[] entries;  /* Section header indices.  */
+  };
+
+/* ELF64 section flags.  */
+
+type Elf64_SectionFlags =
+  struct
+  {
+    Elf64_Xword flags;
+
+    method _print = void:
+      {
+        var s = "";
+
+        if (flags & SHF_WRITE)
+          s = s + "WRITE,";
+        if (flags & SHF_ALLOC)
+          s = s + "ALLOC,";
+        if (flags & SHF_EXECINSTR)
+          s = s + "EXECINSTR,";
+        if (flags & SHF_MERGE)
+          s = s + "MERGE,";
+        if (flags & SHF_STRINGS)
+          s = s + "STRINGS,";
+        if (flags & SHF_INFO_LINK)
+          s = s + "INFO_LINK,";
+        if (flags & SHF_LINK_ORDER)
+          s = s + "LINK_ORDER,";
+        if (flags & SHF_OS_NONCONFORMING)
+          s = s + "OS_NONCONFORMING,";
+        if (flags & SHF_GROUP)
+          s = s + "GROUP,";
+        if (flags & SHF_TLS)
+          s = s + "TLS,";
+        if (flags & SHF_COMPRESSED)
+          s = s + "COMPRESSED,";
+        if (flags & SHF_MASKOS)
+          /* XXX call os-specific printer in elf-OS.pk */
+          ;
+        if (flags & SHF_MASKPROC)
+          /* XXX call arch-specific printer in elf-ARCH.pk */
+          ;
+
+        print "#<" + rtrim (s, ",") + ">";
+      }
+  };
+
+/* ELF64 section header table entry.
+
+   sh_name specifies the name of the section.  It is an index into the
+   file's string table.
+
+   sh_type is the type of the section, one of the SHT_* values defined
+   above.
+
+   sh_flags is the ORed value of the 1-bit flags SHF_* defined
+   above.  */
+
+type Elf64_Shdr =
+  struct
+  {
+    offset<Elf_Word,B> sh_name;
+    Elf_Word sh_type;
+    Elf64_SectionFlags sh_flags;
+    Elf64_Addr sh_addr;
+    Elf64_Off sh_offset;
+    offset<Elf64_Xword,B> sh_size;
+    Elf_Word sh_link;
+    Elf_Word sh_info;
+    Elf64_Xword sh_addralign;
+    offset<Elf64_Xword,b> sh_entsize;
+  };
+
+/* ELF64 segment flags.  */
+
+type Elf64_SegmentFlags =
+  struct
+  {
+    Elf_Word flags;
+
+    method _print = void:
+      {
+        var s = "";
+
+        if (flags & PF_R)
+          s = s + "R,";
+        if (flags & PF_W)
+          s = s + "W,";
+        if (flags & PF_X)
+          s = s + "X,";
+        if (flags & PF_MASKOS)
+          /* XXX call os-specific printer in elf-OS.pk */
+          ;
+        if (flags & PF_MASKPROC)
+          /* XXX call arch-specific printer in elf-ARCH.pk */
+          ;
+
+        print "#<" + rtrim (s, ",") + ">";
+      }
+  };
+
+/* ELF64 program header table entry.  */
+
+type Elf64_Phdr =
+  struct
+  {
+    Elf_Word p_type;
+    Elf64_SegmentFlags p_flags;
+    Elf64_Off p_offset;
+    Elf64_Addr p_vaddr;
+    Elf64_Addr p_paddr;
+    Elf64_Xword p_filesz;
+    Elf64_Xword p_memsz;
+    Elf64_Xword p_align;
+  };
+
+/* ELF64 file header.  */
+
+type Elf64_Ehdr =
+  struct
+  {
+    struct
+    {
+      byte[4] ei_mag == [0x7fUB, 'E', 'L', 'F'];
+      byte ei_class;
+      byte ei_data :
+        (ei_data == ELFDATA2LSB) ? set_endian (ENDIAN_LITTLE) : set_endian 
(ENDIAN_BIG);
+      byte ei_version;
+      byte ei_osabi;
+      byte ei_abiversion;
+      byte[6] ei_pad;
+      offset<byte,B> ei_nident;
+    } e_ident;
+
+    Elf_Half e_type;
+    Elf_Half e_machine;
+    Elf_Word e_version = EV_CURRENT;
+
+    Elf64_Addr e_entry;
+    Elf64_Off e_phoff;
+    Elf64_Off e_shoff;
+
+    Elf_Word e_flags;
+    offset<Elf_Half,B> e_ehsize;
+    offset<Elf_Half,B> e_phentsize;
+    Elf_Half e_phnum;
+    offset<Elf_Half,B> e_shentsize;
+    Elf_Half e_shnum;
+    Elf_Half e_shstrndx : e_shnum == 0 || e_shstrndx < e_shnum;
+  };
+
+/* ELF64 file.  */
+
+type Elf64_File =
+  struct
+  {
+    Elf64_Ehdr ehdr;
+
+    Elf64_Shdr[ehdr.e_shnum] shdr @ ehdr.e_shoff
+      if ehdr.e_shnum > 0;
+
+    Elf64_Phdr[ehdr.e_phnum] phdr @ ehdr.e_phoff
+      if ehdr.e_phnum > 0;
+
+    /* Given an offset into the ELF file's section string table, return
+       the string.  */
+
+    method get_section_name = (offset<Elf_Word,B> offset) string:
+      {
+        var strtab = ehdr.e_shstrndx;
+        return string @ (shdr[strtab].sh_offset + offset);
+      }
+
+    /* Given a symtab and an offset into its associated symbol string
+       table, return the string.  */
+
+    method get_symbol_name = (Elf64_Shdr symtab, offset<Elf_Word,B> offset) 
string:
+      {
+        var strtab = symtab.sh_link;
+        return string @ (shdr[strtab].sh_offset + offset);
+      }
+
+    /* Given a section name, return an array of section headers in the
+       ELF file having that name.  */
+
+    method get_sections_by_name = (string name) Elf64_Shdr[]:
+      {
+        var sections = Elf64_Shdr[]();
+
+        for (s in shdr where get_section_name (s.sh_name) == name)
+          sections += [s];
+
+        return sections;
+      }
+
+    /* Given a section type (SHT_* value) return an array of section
+       headers in the ELF file with that type.  */
+
+    method get_sections_by_type = (Elf_Word stype) Elf64_Shdr[]:
+      {
+        var sections = Elf64_Shdr[]();
+
+        for (s in shdr where s.sh_type == stype)
+          sections += [s];
+
+        return sections;
+      }
+
+    /* Given a section name, return whether it exists in this
+       file.  */
+
+    method section_name_p = (string name) int:
+      {
+        var sections = Elf64_Shdr[]();
+
+        try sections = get_sections_by_name (name);
+        catch if E_inval { return 0; }
+
+        return sections'length;
+      }
+
+    /* Given an offset, return the string stored at that offset in the
+       "default" string table of the ELF file.  This is the string table
+       section named ".strtab".  If such a section doesn't exist, or it
+       doesn't contain a string table, then raise E_inval.  */
+    method get_string = (offset<Elf_Word,B> offset) string:
+     {
+       if (!section_name_p (".strtab"))
+          raise E_inval;
+
+       var strtab = get_sections_by_name (".strtab")[0];
+       return string @ strtab.sh_offset + offset;
+     }
+
+    /* Return the signature corresponding to a given group section.
+       If the given section header doesn't correspond to a group
+       section then raise E_inval.  */
+
+    method get_group_signature = (Elf64_Shdr section) string:
+      {
+        if (section.sh_type != SHT_GROUP)
+          raise E_inval;
+
+        var symtab = shdr[section.sh_link];
+        var symtab_data
+          = Elf64_Sym [symtab.sh_size] @ symtab.sh_offset;
+        var symbol = symtab_data[section.sh_info];
+        var symbol_name = get_symbol_name (symtab, symbol.st_name);
+
+        return symbol_name;
+      }
+
+    /* Return an array of strings with the signatures of the section
+       groups present in this ELF file.  */
+
+    method get_group_signatures = string[]:
+      {
+        var signatures = string[]();
+
+        for (section in shdr where section.sh_type == SHT_GROUP)
+          signatures += [get_group_signature (section)];
+
+        return signatures;
+      }
+
+    /* Given the name of a section group, return an array with the
+       section headers corresponding to all the sections in that
+       group.  If the given name doesn't identify a section group in
+       the ELF file then return an empty array.  */
+
+    method get_section_group = (string group_name) Elf64_Shdr[]:
+      {
+        var section_group = Elf64_Shdr[]();
+
+        var group_sections = get_sections_by_type (SHT_GROUP);
+        for (sec in group_sections
+             where get_group_signature (sec) == group_name)
+          {
+            var group_entries
+              = (Elf_Word[sec.sh_size - sizeof (Elf_Word)]
+                 @ sec.sh_offset + sizeof (Elf_Word));
+
+            for (entry in group_entries)
+              section_group += [shdr[entry]];
+
+            break;
+         }
+
+       return section_group;
+     }
+  };
diff --git a/pickles/elf-common.pk b/pickles/elf-common.pk
new file mode 100644
index 00000000..5fb68f5c
--- /dev/null
+++ b/pickles/elf-common.pk
@@ -0,0 +1,311 @@
+/* elf-common.pk - ELF definitions common to 32 and 64 bits.  */
+
+/* Copyright (C) 2019, 2020, 2021 Jose E. Marchesi.  */
+
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Basic types.  */
+
+type Elf_Half = uint<16>,
+     Elf_Word = uint<32>,
+     Elf_Sword = int<32>;
+
+/* ELF versions.  */
+
+var EV_NONE = 0, /* Invalid ELF version.  */
+    EV_CURRENT = 1;
+
+/* The different kind of ELF files.  */
+
+var ET_NONE = 0,  /* No file type.  */
+    ET_REL  = 1,  /* Relocatable file.  */
+    ET_EXEC = 2,  /* Position-dependent executable.  */
+    ET_DYN  = 3,  /* Position-independent executable or shared object.  */
+    ET_CORE = 4;  /* Core file.  */
+
+/* ELF machine codes.  */
+
+var EM_NONE = 0,
+    EM_RISCV = 243;
+
+/* ELF symbol bindings.  */
+
+var STB_LOCAL = 0,
+    STB_GLOBAL = 1,
+    STB_WEAK = 2,
+    STB_LOOS = 10,
+    STB_HIOS = 12,
+    STB_LOPROC = 13,
+    STB_HIPROC = 15;
+
+var elf_stb_names =
+  ["local","global","weak",.[9]="reserved",.[12]="os",.[15]="proc"];
+
+/* ELF symbol types.  */
+
+var STT_NOTYPE = 0,
+    STT_OBJECT = 1,
+    STT_FUNC = 2,
+    STT_SECTION = 3,
+    STT_FILE = 4,
+    STT_COMMON = 5,
+    STT_TLS = 6,
+    STT_NUM = 7,
+    STT_LOOS = 10,
+    STT_GNU_IFUNC = 10,
+    STT_HIOS = 12,
+    STT_LOPROC = 13,
+    STT_HIPROC = 15;
+
+var elf_stt_names =
+  ["notype", "object", "func", "section", "file", "common",
+   "tls", "num", "8", "9", "gnu_ifunc", "os11", "os12",
+   "loproc13", "loproc14", "loproc15"];
+
+/* ELF symbol visibility.  */
+
+var STV_DEFAULT = 0,
+    STV_INTERNAL = 1,
+    STV_HIDDEN = 2,
+    STV_PROTECTED = 3;
+
+var elf_stv_names =
+  ["default", "internal", "hidden", "protected"];
+
+/* Compression algorithm identificators.  */
+
+var ELFCOMPRESS_ZLIB = 1,
+    ELFCOMPRESS_LOOS = 0x6000_0000,
+    ELFCOMPRESS_HIOS = 0x6fff_ffff,
+    ELFCOMPRESS_LOPROC = 0x7000_0000,
+    ELFCOMPRESS_HIPROC = 0x7fff_ffff;
+
+/* Dynamic tags.  */
+
+var DT_NULL = 0,  /* Tags the end of the dynamic array.  */
+    /* d_val holds the string table offset of a null-terminated
+       string, giving the name of a needed library.  The dynamic array
+       may.  contain multiple entries with this type.  */
+    DT_NEEDED = 1,
+    /* d_val holds the total size, in bytes, of the relocation
+       entries associated with the procedure linkage table.  If an
+       entry of type DT_JMPREL is present, a DT_PLTRELSZ must
+       accompany it.  */
+    DT_PLTRELSZ = 2,
+    /* d_ptr holds an address associated with the procedure linkage
+       table and/or the global offset table.  */
+    DT_PLTGOT = 3,
+    /* d_ptr holds the address of the symbol hash table.  This hash
+       table refers to the symbol table referenced by the DT_SYMTAB
+       element.  */
+    DT_HASH = 4,
+    /* d_ptr holds the address of the string table.  Symbol names,
+       library names, and other strings reside in this table.  */
+    DT_STRTAB = 5,
+    /* d_ptr holds the address of the symbol table.  */
+    DT_SYMTAB = 6,
+    /* d_ptr holds the address of a relocation table.  Entries in the
+       table have explicit addends.  An object file may have multiple
+       relocation sections.  If this element is present, the dynamic
+       vector must also have DT_RELASZ and DT_RELAENT elements.  */
+    DT_RELA = 7,
+    /* d_val holds the total size, in bytes, of the DT_RELA relocation
+       entry.  */
+    DT_RELASZ = 8,
+    /* d_val holds the size, in bytes, of the DT_RELA relocation
+       entry.  */
+    DT_RELAENT = 9,
+    /* d_val holds the size, in bytes, of the string table.  */
+    DT_STRSZ = 10,
+    /* d_val holds the size, in bytes, of a symbol table entry.  */
+    DT_SYMENT = 11,
+    /* d_ptr holds the addresss of the initialization function.  */
+    DT_INIT = 12,
+    /* d_ptr holds the address of the finalization function.  */
+    DT_FINI = 13,
+    /* d_val holds the string table offset of a null-terminated
+       string, giving the name of the shared object.  The offset is an
+       index into the table recorded in the DT_STRTAB entry.  */
+    DT_SONAME = 14,
+    /* d_val holds the string table offset of a null-terminated search
+       library search path string.  The offset is an index into the
+       table recorded in the DT_STRTAB entry.  This entry is at level
+       2.  Its use has been superseded by DT_RUNPATH.  */
+    DT_RPATH = 15,
+    /* This element's presence in a shared object library alters the
+       dynamic linker's symbol resolution algorithm for references
+       within the library.  */
+    DT_SYMBOLIC = 16,
+    /* d_ptr holds the address of a relocation table containing rela
+       relocations.  If this element is present, the dynamic structure
+       must also have DT_RELSZ and DT_RELENT elements.  */
+    DT_REL = 17,
+    /* d_val holds the total size, in bytes, of the DT_REL relocation
+       table.  */
+    DT_RELSZ = 18,
+    /* d_val holds the size, in bytes, of the DT_REL relocation
+       entry. */
+    DT_RELENT = 19,
+    /* d_val specifies the type of relocation entry to which the
+       procedure linkage table refers: DT_REL or DT_RELA.  */
+    DT_PLTREL = 20,
+    /* This tag is used for debugging.  Its contents are not
+       specified for the ABI.  */
+    DT_DEBUG = 21,
+    /* This tag's absence signifies that no relocation entry should
+       cause a modification to a non-writable segment, as specified
+       by the segment permissions in the program header table.  If
+       this tag is present, one or more relocation entries might
+       request modifications to a non-writable segement, and the
+       dynamic linker can prepare accordingly.  This entry is at
+       level 2.  Its use has been superseded by the DF_TEXTREL
+       flag.  */
+    DT_TEXTREL = 22,
+    /* d_ptr holds the address of relocation entries associated
+       solely with the procedure linkage table.  If this tag is
+       present, the related entries of types DT_PLTRELSZ and
+       DT_PLTREL must also be present.  */
+    DT_JMPREL = 23,
+    /* If present, this tag instructs the dynamic linker to process
+       all relocations for the object containing this entry before
+       transferring control to the program.  */
+    DT_BIND_NOW = 24,
+    /* d_ptr holds the address of the array of pointers to
+         initialization functions.  */
+    DT_INIT_ARRAY = 25,
+    /* d_ptr holds the address of the array of pointers to
+         finalization functions.  */
+    DT_FINI_ARRAY = 26,
+    /* d_val holds the size in bytes of the array of initialization
+       functions pointed to by the DT_INIT_ARRAY entry.  If an
+       object has a DT_INIT_ARRAY entry, it must also have a
+       DT_INIT_ARRAYSZ entry.  */
+    DT_INIT_ARRAYSZ = 27,
+    /* d_val holds the size in bytes of the array of termination
+       functions pointed to by the DT_FINI_ARRAY entry.  If an
+       object has a DT_fINI_ARRAY entry, it must also have a
+       DT_FINI_ARRAYSZ entry.  */
+    DT_FINI_ARRAYSZ = 28,
+    /* d_val holds the string table offset of a null-terminated
+       library search path string.  The offset is an index into the
+       table recorded in the DT_STRTAB entry.  */
+    DT_RUNPATH = 29,
+    /* d_val holds flag values specific to the object being
+       loaded.  */
+    DT_FLAGS = 30,
+    DT_ENCODING = 32,
+    /* d_ptr holds the address of the array of pointers to
+       pre-initialization functions.  */
+    DT_PREINIT_ARRAY = 32,
+    /* d_val holds the size in bytes of the array of
+       pre-initialization functions pointed to by the
+       DT_PREINIT_ARRAY entry.  */
+    DT_PREINIT_ARRAYSZ = 33,
+    /* d_ptr holds the address of the SHT_SYMTAB_SHNDX section
+       associated with the dynamic symbol table referenced by the
+       DT_SYMTAB element.  */
+    DT_SYMTAB_SHNDX = 34,
+    DT_LOOS = 0x6000_000d,
+    DT_HIOS = 0x6fff_f000,
+    DT_LOPROC = 0x7000_0000,
+    DT_SPARC_REGISTER = 0x7000_0001,
+    DT_HIPROC = 0x7fff_ffff;
+
+/* Definitions related to section groups.  */
+
+var GRP_COMDAT = 1,
+    GRP_MASKOS = 0x0ff0_0000,
+    GRP_MASKPROC = 0xf000_0000;
+
+/* Section types.  */
+
+var SHT_NULL = 0,
+    SHT_PROGBITS = 1,
+    SHT_SYMTAB = 2,
+    SHT_STRTAB = 3,
+    SHT_RELA = 4,
+    SHT_HASH = 5,
+    SHT_DYNAMIC = 6,
+    SHT_NOTE = 7,
+    SHT_NOBITS = 8,
+    SHT_REL = 9,
+    SHT_SHLIB = 10,
+    SHT_DYNSYM = 11,
+    SHT_INIT_ARRAY = 14,
+    SHT_FINI_ARRAY = 15,
+    SHT_PREINIT_ARRAY = 16,
+    SHT_GROUP = 17,
+    SHT_SYMTAB_SHNDX = 18,
+    SHT_LOOS = 0x6000_0000,
+    SHT_HIOS = 0x6fff_ffff,
+    SHT_LOUSER = 0x8000_0000,
+    SHT_HIUSER = 0xffff_ffff;
+
+/* Section Attribute Flags.  */
+
+var SHF_WRITE = 0x1,
+    SHF_ALLOC = 0x2,
+    SHF_EXECINSTR = 0x4,
+    SHF_MERGE = 0x10,
+    SHF_STRINGS = 0x20,
+    SHF_INFO_LINK = 0x40,
+    SHF_LINK_ORDER = 0x80,
+    SHF_OS_NONCONFORMING = 0x100,
+    SHF_GROUP = 0x200,
+    SHF_TLS = 0x400,
+    SHF_COMPRESSED = 0x800,
+    SHF_MASKOS = 0x0ff0_0000,
+    SHF_MASKPROC = 0xf000_0000;
+
+/* Segment types.  */
+
+var PT_NULL = 0,
+    PT_LOAD = 1,
+    PT_DYNAMIC = 2,
+    PT_INTERP = 3,
+    PT_NOTE = 4,
+    PT_SHLIB = 5,
+    PT_PHDR = 6,
+    PT_TLS = 7,
+    PT_LOOS = 0x6000_0000,
+    PT_HIOS = 0x6fff_ffff,
+    PT_LOPROC = 0x7000_0000,
+    PT_HIPROC = 0x7fff_ffff;
+
+/* Segment Flags.  */
+
+var PF_X = 0x1,
+    PF_W = 0x2,
+    PF_R = 0x4,
+    PF_MASKOS = 0x0ff0_0000,
+    PF_MASKPROC = 0xf000_0000;
+
+/* Encoding of the ELF file.  */
+
+var ELFDATANONE = 0,
+    ELFDATA2LSB = 1,
+    ELFDATA2MSB = 2;
+
+/* ELF hash table.  */
+
+type Elf_Hash_Table =
+  struct
+  {
+    Elf_Word nbucket;
+    Elf_Word nchain;
+
+    Elf_Word[nbucket] bucket;
+    Elf_Word[nchain] chain;
+  };
diff --git a/pickles/elf.pk b/pickles/elf.pk
index 6d066dbc..639a77d0 100644
--- a/pickles/elf.pk
+++ b/pickles/elf.pk
@@ -29,707 +29,6 @@
  * with these names.
  */
 
-type Elf_Half = uint<16>,
-     Elf_Word = uint<32>,
-     Elf64_Xword = uint<64>,
-     Elf64_Sxword = int<64>,
-     Elf64_Addr = offset<uint<64>,B>,
-     Elf64_Off = offset<uint<64>,B>;
-
-/****** ELF versions and file types.  ******/
-
-var EV_NONE = 0, /* Invalid ELF version.  */
-    EV_CURRENT = 1;
-
-var ET_NONE = 0,  /* No file type.  */
-    ET_REL  = 1,  /* Relocatable file.  */
-    ET_EXEC = 2,  /* Position-dependent executable.  */
-    ET_DYN  = 3,  /* Position-independent executable or shared object.  */
-    ET_CORE = 4;  /* Core file.  */
-
-/****** ELF machine codes.  ********/
-
-var EM_NONE = 0,
-    EM_RISCV = 243;
-
-/****** ELF hash table.  ******/
-
-type Elf_Hash_Table =
-  struct
-  {
-    Elf_Word nbucket;
-    Elf_Word nchain;
-
-    Elf_Word[nbucket] bucket;
-    Elf_Word[nchain] chain;
-  };
-
-/****** Relocation Entries.  ******/
-
-/* r_sym is the symbol table index with respect to which the
-   relocation must be made.
-
-   r_type is the type of relocation to apply, which is
-   architecture-specific.  See the elf-ARCH pickles.  */
-
-type Elf64_RelInfo =
-  struct Elf64_Xword
-  {
-    uint<32> r_sym;
-    uint<32> r_type;
-  };
-
-/* r_offset holds a section offset in relocatable files, a virtual
-   address in executable and shared object files.
-
-   r_addend holds a constant value to be added to the relocation's
-   value.  In architectures using Rel relocations this addend is
-   somehow stored in the relocation's memory location.  */
-
-type Elf64_Rel =
-  struct
-  {
-    Elf64_Addr r_offset;
-    Elf64_RelInfo r_info;
-  };
-
-type Elf64_Rela =
-  struct
-  {
-    Elf64_Addr r_offset;
-    Elf64_RelInfo r_info;
-    Elf64_Sxword r_addend;
-  };
-
-/****** Symbols.  ******/
-
-/* ELF symbol bindings.  */
-
-var STB_LOCAL = 0,
-    STB_GLOBAL = 1,
-    STB_WEAK = 2,
-    STB_LOOS = 10,
-    STB_HIOS = 12,
-    STB_LOPROC = 13,
-    STB_HIPROC = 15;
-
-var elf_stb_names =
-  ["local","global","weak",.[9]="reserved",.[12]="os",.[15]="proc"];
-
-/* ELF symbol types.  */
-
-var STT_NOTYPE = 0,
-    STT_OBJECT = 1,
-    STT_FUNC = 2,
-    STT_SECTION = 3,
-    STT_FILE = 4,
-    STT_COMMON = 5,
-    STT_TLS = 6,
-    STT_NUM = 7,
-    STT_LOOS = 10,
-    STT_GNU_IFUNC = 10,
-    STT_HIOS = 12,
-    STT_LOPROC = 13,
-    STT_HIPROC = 15;
-
-var elf_stt_names =
-  ["notype", "object", "func", "section", "file", "common",
-   "tls", "num", "8", "9", "gnu_ifunc", "os11", "os12",
-   "loproc13", "loproc14", "loproc15"];
-
-/* ELF symbol visibility.  */
-
-var STV_DEFAULT = 0,
-    STV_INTERNAL = 1,
-    STV_HIDDEN = 2,
-    STV_PROTECTED = 3;
-
-var elf_stv_names =
-  ["default", "internal", "hidden", "protected"];
-
-type Elf64_Sym =
-  struct
-  {
-    offset<Elf_Word,B> st_name;
-    struct uint<8>
-    {
-      uint<4> st_bind;
-      uint<4> st_type;
-
-      method _print = void:
-        {
-          printf ("#<stb:%s,stt:%s>",
-                  elf_stb_names[st_bind], elf_stt_names[st_type]);
-        }
-    } st_info;
-
-    struct uint<8>
-    {
-      uint<5>;
-      uint<3> st_visibility;
-
-      method _print = void:
-        {
-          print "#<stv:" + elf_stv_names[st_visibility] + ">";
-        }
-    } st_other;
-
-    Elf_Half st_shndx;
-    Elf64_Addr st_value;
-    Elf64_Xword st_size;
-  };
-
-/****** Notes.  *****/
-
-type Elf64_Note =
-  struct
-  {
-    /* The first `namesz' bytes in `name' contain a NULL-terminated
-    character representation of the entry's owner or originator.  */
-    Elf64_Xword namesz;
-
-    /* The first `descsz' bytes in `desc' hold the note descriptor.
-    The ABI places no constraints on a descriptor's contents.  */
-    Elf64_Xword descsz;
-
-    byte[namesz] name;
-    byte[alignto (OFFSET, 8#B)];
-
-    byte[descsz] desc;
-    byte[alignto (OFFSET, 8#B)];
-  };
-
-/****** Compressed sections.  *********/
-
-/* Compression algorithm identificators.  */
-
-var ELFCOMPRESS_ZLIB = 1,
-    ELFCOMPRESS_LOOS = 0x6000_0000,
-    ELFCOMPRESS_HIOS = 0x6fff_ffff,
-    ELFCOMPRESS_LOPROC = 0x7000_0000,
-    ELFCOMPRESS_HIPROC = 0x7fff_ffff;
-
-/* The following header is used in sections iwth SHF_COMPRESSED.  */
-
-type Elf64_Chdr =
-  struct
-  {
-    Elf_Word ch_type;
-    Elf_Word ch_reserved;
-    offset<Elf64_Xword,B> ch_size;
-    offset<Elf64_Xword,B> ch_addralign;
-  };
-
-/****** ELF dynamic section.  ******/
-
-
-var DT_NULL = 0,  /* Tags the end of the dynamic array.  */
-    /* d_val holds the string table offset of a null-terminated
-       string, giving the name of a needed library.  The dynamic array
-       may.  contain multiple entries with this type.  */
-    DT_NEEDED = 1,
-    /* d_val holds the total size, in bytes, of the relocation
-       entries associated with the procedure linkage table.  If an
-       entry of type DT_JMPREL is present, a DT_PLTRELSZ must
-       accompany it.  */
-    DT_PLTRELSZ = 2,
-    /* d_ptr holds an address associated with the procedure linkage
-       table and/or the global offset table.  */
-    DT_PLTGOT = 3,
-    /* d_ptr holds the address of the symbol hash table.  This hash
-       table refers to the symbol table referenced by the DT_SYMTAB
-       element.  */
-    DT_HASH = 4,
-    /* d_ptr holds the address of the string table.  Symbol names,
-       library names, and other strings reside in this table.  */
-    DT_STRTAB = 5,
-    /* d_ptr holds the address of the symbol table.  */
-    DT_SYMTAB = 6,
-    /* d_ptr holds the address of a relocation table.  Entries in the
-       table have explicit addends.  An object file may have multiple
-       relocation sections.  If this element is present, the dynamic
-       vector must also have DT_RELASZ and DT_RELAENT elements.  */
-    DT_RELA = 7,
-    /* d_val holds the total size, in bytes, of the DT_RELA relocation
-       entry.  */
-    DT_RELASZ = 8,
-    /* d_val holds the size, in bytes, of the DT_RELA relocation
-       entry.  */
-    DT_RELAENT = 9,
-    /* d_val holds the size, in bytes, of the string table.  */
-    DT_STRSZ = 10,
-    /* d_val holds the size, in bytes, of a symbol table entry.  */
-    DT_SYMENT = 11,
-    /* d_ptr holds the addresss of the initialization function.  */
-    DT_INIT = 12,
-    /* d_ptr holds the address of the finalization function.  */
-    DT_FINI = 13,
-    /* d_val holds the string table offset of a null-terminated
-       string, giving the name of the shared object.  The offset is an
-       index into the table recorded in the DT_STRTAB entry.  */
-    DT_SONAME = 14,
-    /* d_val holds the string table offset of a null-terminated search
-       library search path string.  The offset is an index into the
-       table recorded in the DT_STRTAB entry.  This entry is at level
-       2.  Its use has been superseded by DT_RUNPATH.  */
-    DT_RPATH = 15,
-    /* This element's presence in a shared object library alters the
-       dynamic linker's symbol resolution algorithm for references
-       within the library.  */
-    DT_SYMBOLIC = 16,
-    /* d_ptr holds the address of a relocation table containing rela
-       relocations.  If this element is present, the dynamic structure
-       must also have DT_RELSZ and DT_RELENT elements.  */
-    DT_REL = 17,
-    /* d_val holds the total size, in bytes, of the DT_REL relocation
-       table.  */
-    DT_RELSZ = 18,
-    /* d_val holds the size, in bytes, of the DT_REL relocation
-       entry. */
-    DT_RELENT = 19,
-    /* d_val specifies the type of relocation entry to which the
-       procedure linkage table refers: DT_REL or DT_RELA.  */
-    DT_PLTREL = 20,
-    /* This tag is used for debugging.  Its contents are not
-       specified for the ABI.  */
-    DT_DEBUG = 21,
-    /* This tag's absence signifies that no relocation entry should
-       cause a modification to a non-writable segment, as specified
-       by the segment permissions in the program header table.  If
-       this tag is present, one or more relocation entries might
-       request modifications to a non-writable segement, and the
-       dynamic linker can prepare accordingly.  This entry is at
-       level 2.  Its use has been superseded by the DF_TEXTREL
-       flag.  */
-    DT_TEXTREL = 22,
-    /* d_ptr holds the address of relocation entries associated
-       solely with the procedure linkage table.  If this tag is
-       present, the related entries of types DT_PLTRELSZ and
-       DT_PLTREL must also be present.  */
-    DT_JMPREL = 23,
-    /* If present, this tag instructs the dynamic linker to process
-       all relocations for the object containing this entry before
-       transferring control to the program.  */
-    DT_BIND_NOW = 24,
-    /* d_ptr holds the address of the array of pointers to
-         initialization functions.  */
-    DT_INIT_ARRAY = 25,
-    /* d_ptr holds the address of the array of pointers to
-         finalization functions.  */
-    DT_FINI_ARRAY = 26,
-    /* d_val holds the size in bytes of the array of initialization
-       functions pointed to by the DT_INIT_ARRAY entry.  If an
-       object has a DT_INIT_ARRAY entry, it must also have a
-       DT_INIT_ARRAYSZ entry.  */
-    DT_INIT_ARRAYSZ = 27,
-    /* d_val holds the size in bytes of the array of termination
-       functions pointed to by the DT_FINI_ARRAY entry.  If an
-       object has a DT_fINI_ARRAY entry, it must also have a
-       DT_FINI_ARRAYSZ entry.  */
-    DT_FINI_ARRAYSZ = 28,
-    /* d_val holds the string table offset of a null-terminated
-       library search path string.  The offset is an index into the
-       table recorded in the DT_STRTAB entry.  */
-    DT_RUNPATH = 29,
-    /* d_val holds flag values specific to the object being
-       loaded.  */
-    DT_FLAGS = 30,
-    DT_ENCODING = 32,
-    /* d_ptr holds the address of the array of pointers to
-       pre-initialization functions.  */
-    DT_PREINIT_ARRAY = 32,
-    /* d_val holds the size in bytes of the array of
-       pre-initialization functions pointed to by the
-       DT_PREINIT_ARRAY entry.  */
-    DT_PREINIT_ARRAYSZ = 33,
-    /* d_ptr holds the address of the SHT_SYMTAB_SHNDX section
-       associated with the dynamic symbol table referenced by the
-       DT_SYMTAB element.  */
-    DT_SYMTAB_SHNDX = 34,
-    DT_LOOS = 0x6000_000d,
-    DT_HIOS = 0x6fff_f000,
-    DT_LOPROC = 0x7000_0000,
-    DT_SPARC_REGISTER = 0x7000_0001,
-    DT_HIPROC = 0x7fff_ffff;
-
-type Elf64_Dyn =
-  struct
-  {
-    Elf64_Sxword d_tag;
-
-    union
-      {
-      /* Entries in the dynamic tags in a position >= DT_ENCODING
-         follow an uniform rule regarding what field is used for the
-         data: even entries use d_ptr while odd entries use d_val.  */
-
-        Elf64_Addr d_ptr
-          : (d_tag in [DT_PLTGOT, DT_HASH, DT_STRTAB, DT_SYMTAB, DT_RELA,
-                       DT_SYMENT, DT_INIT, DT_FINI, DT_REL, DT_JMPREL,
-                       DT_INIT_ARRAY, DT_FINI_ARRAY]
-             || (d_tag >= DT_ENCODING && d_tag %2 != 0));
-
-        Elf64_Xword d_val;
-    } d_data;
-  };
-
-/****** Section Groups.  ******/
-
-var GRP_COMDAT = 1,
-    GRP_MASKOS = 0x0ff0_0000,
-    GRP_MASKPROC = 0xf000_0000;
-
-type Elf64_Group =
-  struct
-  {
-    Elf_Word flags;
-    Elf_Word[] entries;  /* Section header indices.  */
-  };
-
-/****** Sections.  ******/
-
-/* Section types.  */
-
-var SHT_NULL = 0,
-    SHT_PROGBITS = 1,
-    SHT_SYMTAB = 2,
-    SHT_STRTAB = 3,
-    SHT_RELA = 4,
-    SHT_HASH = 5,
-    SHT_DYNAMIC = 6,
-    SHT_NOTE = 7,
-    SHT_NOBITS = 8,
-    SHT_REL = 9,
-    SHT_SHLIB = 10,
-    SHT_DYNSYM = 11,
-    SHT_INIT_ARRAY = 14,
-    SHT_FINI_ARRAY = 15,
-    SHT_PREINIT_ARRAY = 16,
-    SHT_GROUP = 17,
-    SHT_SYMTAB_SHNDX = 18,
-    SHT_LOOS = 0x6000_0000,
-    SHT_HIOS = 0x6fff_ffff,
-    SHT_LOUSER = 0x8000_0000,
-    SHT_HIUSER = 0xffff_ffff;
-
-/* Section Attribute Flags.  */
-
-var SHF_WRITE = 0x1,
-    SHF_ALLOC = 0x2,
-    SHF_EXECINSTR = 0x4,
-    SHF_MERGE = 0x10,
-    SHF_STRINGS = 0x20,
-    SHF_INFO_LINK = 0x40,
-    SHF_LINK_ORDER = 0x80,
-    SHF_OS_NONCONFORMING = 0x100,
-    SHF_GROUP = 0x200,
-    SHF_TLS = 0x400,
-    SHF_COMPRESSED = 0x800,
-    SHF_MASKOS = 0x0ff0_0000,
-    SHF_MASKPROC = 0xf000_0000;
-
-type Elf64_SectionFlags =
-  struct
-  {
-    Elf64_Xword flags;
-
-    method _print = void:
-      {
-        var s = "";
-
-        if (flags & SHF_WRITE)
-          s = s + "WRITE,";
-        if (flags & SHF_ALLOC)
-          s = s + "ALLOC,";
-        if (flags & SHF_EXECINSTR)
-          s = s + "EXECINSTR,";
-        if (flags & SHF_MERGE)
-          s = s + "MERGE,";
-        if (flags & SHF_STRINGS)
-          s = s + "STRINGS,";
-        if (flags & SHF_INFO_LINK)
-          s = s + "INFO_LINK,";
-        if (flags & SHF_LINK_ORDER)
-          s = s + "LINK_ORDER,";
-        if (flags & SHF_OS_NONCONFORMING)
-          s = s + "OS_NONCONFORMING,";
-        if (flags & SHF_GROUP)
-          s = s + "GROUP,";
-        if (flags & SHF_TLS)
-          s = s + "TLS,";
-        if (flags & SHF_COMPRESSED)
-          s = s + "COMPRESSED,";
-        if (flags & SHF_MASKOS)
-          /* XXX call os-specific printer in elf-OS.pk */
-          ;
-        if (flags & SHF_MASKPROC)
-          /* XXX call arch-specific printer in elf-ARCH.pk */
-          ;
-
-        print "#<" + rtrim (s, ",") + ">";
-      }
-  };
-
-/* sh_name specifies the name of the section.  It is an index into the
-   file's string table.
-
-   sh_type is the type of the section, one of the SHT_* values defined
-   above.
-
-   sh_flags is the ORed value of the 1-bit flags SHF_* defined
-   above.  */
-
-type Elf64_Shdr =
-  struct
-  {
-    offset<Elf_Word,B> sh_name;
-    Elf_Word sh_type;
-    Elf64_SectionFlags sh_flags;
-    Elf64_Addr sh_addr;
-    Elf64_Off sh_offset;
-    offset<Elf64_Xword,B> sh_size;
-    Elf_Word sh_link;
-    Elf_Word sh_info;
-    Elf64_Xword sh_addralign;
-    offset<Elf64_Xword,b> sh_entsize;
-  };
-
-/****** Segments.  ******/
-
-/* Segment types.  */
-
-var PT_NULL = 0,
-    PT_LOAD = 1,
-    PT_DYNAMIC = 2,
-    PT_INTERP = 3,
-    PT_NOTE = 4,
-    PT_SHLIB = 5,
-    PT_PHDR = 6,
-    PT_TLS = 7,
-    PT_LOOS = 0x6000_0000,
-    PT_HIOS = 0x6fff_ffff,
-    PT_LOPROC = 0x7000_0000,
-    PT_HIPROC = 0x7fff_ffff;
-
-/* Segment Flags.  */
-
-var PF_X = 0x1,
-    PF_W = 0x2,
-    PF_R = 0x4,
-    PF_MASKOS = 0x0ff0_0000,
-    PF_MASKPROC = 0xf000_0000;
-
-type Elf64_SegmentFlags =
-  struct
-  {
-    Elf_Word flags;
-
-    method _print = void:
-      {
-        var s = "";
-
-        if (flags & PF_R)
-          s = s + "R,";
-        if (flags & PF_W)
-          s = s + "W,";
-        if (flags & PF_X)
-          s = s + "X,";
-        if (flags & PF_MASKOS)
-          /* XXX call os-specific printer in elf-OS.pk */
-          ;
-        if (flags & PF_MASKPROC)
-          /* XXX call arch-specific printer in elf-ARCH.pk */
-          ;
-
-        print "#<" + rtrim (s, ",") + ">";
-      }
-  };
-
-type Elf64_Phdr =
-  struct
-  {
-    Elf_Word p_type;
-    Elf64_SegmentFlags p_flags;
-    Elf64_Off p_offset;
-    Elf64_Addr p_vaddr;
-    Elf64_Addr p_paddr;
-    Elf64_Xword p_filesz;
-    Elf64_Xword p_memsz;
-    Elf64_Xword p_align;
-  };
-
-var ELFDATANONE = 0,
-    ELFDATA2LSB = 1,
-    ELFDATA2MSB = 2;
-
-type Elf64_Ehdr =
-  struct
-  {
-    struct
-    {
-      byte[4] ei_mag == [0x7fUB, 'E', 'L', 'F'];
-      byte ei_class;
-      byte ei_data :
-        (ei_data == ELFDATA2LSB) ? set_endian (ENDIAN_LITTLE) : set_endian 
(ENDIAN_BIG);
-      byte ei_version;
-      byte ei_osabi;
-      byte ei_abiversion;
-      byte[6] ei_pad;
-      offset<byte,B> ei_nident;
-    } e_ident;
-
-    Elf_Half e_type;
-    Elf_Half e_machine;
-    Elf_Word e_version = EV_CURRENT;
-
-    Elf64_Addr e_entry;
-    Elf64_Off e_phoff;
-    Elf64_Off e_shoff;
-
-    Elf_Word e_flags;
-    offset<Elf_Half,B> e_ehsize;
-    offset<Elf_Half,B> e_phentsize;
-    Elf_Half e_phnum;
-    offset<Elf_Half,B> e_shentsize;
-    Elf_Half e_shnum;
-    Elf_Half e_shstrndx : e_shnum == 0 || e_shstrndx < e_shnum;
-  };
-
-type Elf64_File =
-  struct
-  {
-    Elf64_Ehdr ehdr;
-
-    Elf64_Shdr[ehdr.e_shnum] shdr @ ehdr.e_shoff
-      if ehdr.e_shnum > 0;
-
-    Elf64_Phdr[ehdr.e_phnum] phdr @ ehdr.e_phoff
-      if ehdr.e_phnum > 0;
-
-    /* Given an offset into the ELF file's section string table, return
-       the string.  */
-
-    method get_section_name = (offset<Elf_Word,B> offset) string:
-      {
-        var strtab = ehdr.e_shstrndx;
-        return string @ (shdr[strtab].sh_offset + offset);
-      }
-
-    /* Given a symtab and an offset into its associated symbol string
-       table, return the string.  */
-
-    method get_symbol_name = (Elf64_Shdr symtab, offset<Elf_Word,B> offset) 
string:
-      {
-        var strtab = symtab.sh_link;
-        return string @ (shdr[strtab].sh_offset + offset);
-      }
-
-    /* Given a section name, return an array of section headers in the
-       ELF file having that name.  */
-
-    method get_sections_by_name = (string name) Elf64_Shdr[]:
-      {
-        var sections = Elf64_Shdr[]();
-
-        for (s in shdr where get_section_name (s.sh_name) == name)
-          sections += [s];
-
-        return sections;
-      }
-
-    /* Given a section type (SHT_* value) return an array of section
-       headers in the ELF file with that type.  */
-
-    method get_sections_by_type = (Elf_Word stype) Elf64_Shdr[]:
-      {
-        var sections = Elf64_Shdr[]();
-
-        for (s in shdr where s.sh_type == stype)
-          sections += [s];
-
-        return sections;
-      }
-
-    /* Given a section name, return whether it exists in this
-       file.  */
-
-    method section_name_p = (string name) int:
-      {
-        var sections = Elf64_Shdr[]();
-
-        try sections = get_sections_by_name (name);
-        catch if E_inval { return 0; }
-
-        return sections'length;
-      }
-
-    /* Given an offset, return the string stored at that offset in the
-       "default" string table of the ELF file.  This is the string table
-       section named ".strtab".  If such a section doesn't exist, or it
-       doesn't contain a string table, then raise E_inval.  */
-    method get_string = (offset<Elf_Word,B> offset) string:
-     {
-       if (!section_name_p (".strtab"))
-          raise E_inval;
-
-       var strtab = get_sections_by_name (".strtab")[0];
-       return string @ strtab.sh_offset + offset;
-     }
-
-    /* Return the signature corresponding to a given group section.
-       If the given section header doesn't correspond to a group
-       section then raise E_inval.  */
-
-    method get_group_signature = (Elf64_Shdr section) string:
-      {
-        if (section.sh_type != SHT_GROUP)
-          raise E_inval;
-
-        var symtab = shdr[section.sh_link];
-        var symtab_data
-          = Elf64_Sym [symtab.sh_size] @ symtab.sh_offset;
-        var symbol = symtab_data[section.sh_info];
-        var symbol_name = get_symbol_name (symtab, symbol.st_name);
-
-        return symbol_name;
-      }
-
-    /* Return an array of strings with the signatures of the section
-       groups present in this ELF file.  */
-
-    method get_group_signatures = string[]:
-      {
-        var signatures = string[]();
-
-        for (section in shdr where section.sh_type == SHT_GROUP)
-          signatures += [get_group_signature (section)];
-
-        return signatures;
-      }
-
-    /* Given the name of a section group, return an array with the
-       section headers corresponding to all the sections in that
-       group.  If the given name doesn't identify a section group in
-       the ELF file then return an empty array.  */
-
-    method get_section_group = (string group_name) Elf64_Shdr[]:
-      {
-        var section_group = Elf64_Shdr[]();
-
-        var group_sections = get_sections_by_type (SHT_GROUP);
-        for (sec in group_sections
-             where get_group_signature (sec) == group_name)
-          {
-            var group_entries
-              = (Elf_Word[sec.sh_size - sizeof (Elf_Word)]
-                 @ sec.sh_offset + sizeof (Elf_Word));
-
-            for (entry in group_entries)
-              section_group += [shdr[entry]];
-
-            break;
-         }
-
-       return section_group;
-     }
-  };
+load "elf-common.pk";
+load "elf-32.pk";
+load "elf-64.pk";
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]