elf2out from netbsd (ported for minix aout)

This commit is contained in:
Ben Gras 2011-02-23 12:21:21 +00:00
parent 36f9c1155a
commit 659dd75c78
6 changed files with 1587 additions and 0 deletions

View file

@ -35,6 +35,10 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
xargs yacc yes zdump zic zmodem pkgin_cd \
mktemp
.if ${COMPILER_TYPE} == "gnu"
SUBDIR += elf2aout
.endif
.if ${ARCH} == "i386"
SUBDIR+= atnormalize dosread fdisk loadfont \
mixer autopart part partition playwave postmort \

View file

@ -0,0 +1,3 @@
PROG= elf2aout
.include <bsd.prog.mk>

View file

@ -0,0 +1,66 @@
.\" $NetBSD: elf2aout.1,v 1.9 2003/02/25 10:35:40 wiz Exp $
.\"
.\" Copyright 1996 The Board of Trustees of The Leland Stanford
.\" Junior University. All Rights Reserved.
.\"
.\" Author: Jonathan Stone
.\"
.\" Permission to use, copy, modify, and distribute this
.\" software and its documentation for any purpose and without
.\" fee is hereby granted, provided that the above copyright
.\" notice and the above authorship notice appear in all copies.
.\" Stanford University makes no representations about the suitability
.\" of this software for any purpose. It is provided "as is" without
.\" express or implied warranty.
.Dd September 30, 1996
.Dt ELF2AOUT 1
.Os
.Sh NAME
.Nm elf2aout
.Nd convert a NetBSD ELF-format executable to NetBSD a.out format
.Sh SYNOPSIS
.Nm elf2aout
.Ar elf-file
.Ar aout-file
.Sh DESCRIPTION
Reads a fully-linked ELF executable (such as a linked kernel)
and produces an equivalent a.out format executable file.
.Pp
The
.Nm
utility is used to convert native
.Nx
ELF binaries
to a.out format, for compatibility with bootblocks and kernel-reading
utilities like
.Xr kvm 3
and
.Xr kvm_mkdb 8 ,
which currently expect an a.out format kernel.
.\" .Sh DIAGNOSTICS
.Sh SEE ALSO
.Xr elf2ecoff 1 ,
.Xr ld 1 ,
.Xr kvm 3 ,
.Xr a.out 5 ,
.Xr elf 5 ,
.Xr kvm_mkdb 8
.Sh HISTORY
.Nm
was originally developed for
.Nx Ns Tn /pmax
by Ted Lemon
and was first distributed with the pmax port of
.Nx 1.1 .
.Sh BUGS
.Nm
assumes there are no multiply-referenced symbols in the input ELF symbol
section.
It may be necessary to link with
.Fl x
to avoid such duplicate symbols.
.Pp
In some environments, the GNU binutils
.Xr objcopy 1
utility may be a better solution than
.Nm .

View file

@ -0,0 +1,531 @@
/* $NetBSD: elf2aout.c,v 1.11 2004/04/23 02:55:11 simonb Exp $ */
/*
* Copyright (c) 1995
* Ted Lemon (hereinafter referred to as the author)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* elf2aout.c
This program converts an elf executable to a NetBSD a.out executable.
The minimal symbol table is copied, but the debugging symbols and
other informational sections are not. */
#include <sys/types.h>
#include <a.out.h>
#include "exec_elf.h"
#include <a.out.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
struct sect {
unsigned long vaddr;
unsigned long len;
};
void combine __P((struct sect *, struct sect *, int));
int phcmp __P((const void *, const void *));
char *saveRead __P((int file, off_t offset, off_t len, char *name));
void copy __P((int, int, off_t, off_t));
void translate_syms __P((int, int, off_t, off_t, off_t, off_t));
int *symTypeTable;
int
main(int argc, char **argv)
{
Elf32_Ehdr ex;
Elf32_Phdr *ph;
Elf32_Shdr *sh;
char *shstrtab;
int strtabix, symtabix;
int i;
struct sect text, data, bss;
struct exec aex;
int infile, outfile;
unsigned long cur_vma = ULONG_MAX;
int symflag = 0;
strtabix = symtabix = -1;
text.len = data.len = bss.len = 0;
text.vaddr = data.vaddr = bss.vaddr = 0;
/* Check args... */
if (argc < 3 || argc > 4) {
usage:
fprintf(stderr,
"usage: elf2aout <elf executable> <a.out executable> [-s]\n");
exit(1);
}
if (argc == 4) {
if (strcmp(argv[3], "-s"))
goto usage;
symflag = 1;
}
/* Try the input file... */
if ((infile = open(argv[1], O_RDONLY)) < 0) {
fprintf(stderr, "Can't open %s for read: %s\n",
argv[1], strerror(errno));
exit(1);
}
/* Read the header, which is at the beginning of the file... */
i = read(infile, &ex, sizeof ex);
if (i != sizeof ex) {
fprintf(stderr, "ex: %s: %s.\n",
argv[1], i ? strerror(errno) : "End of file reached");
exit(1);
}
/* Read the program headers... */
ph = (Elf32_Phdr *) saveRead(infile, ex.e_phoff,
ex.e_phnum * sizeof(Elf32_Phdr), "ph");
/* Read the section headers... */
sh = (Elf32_Shdr *) saveRead(infile, ex.e_shoff,
ex.e_shnum * sizeof(Elf32_Shdr), "sh");
/* Read in the section string table. */
shstrtab = saveRead(infile, sh[ex.e_shstrndx].sh_offset,
sh[ex.e_shstrndx].sh_size, "shstrtab");
/* Find space for a table matching ELF section indices to a.out symbol
* types. */
symTypeTable = (int *) malloc(ex.e_shnum * sizeof(int));
if (!symTypeTable) {
fprintf(stderr, "symTypeTable: can't allocate.\n");
exit(1);
}
memset(symTypeTable, 0, ex.e_shnum * sizeof(int));
/* Look for the symbol table and string table... Also map section
* indices to symbol types for a.out */
for (i = 0; i < ex.e_shnum; i++) {
char *name = shstrtab + sh[i].sh_name;
if (!strcmp(name, ".symtab"))
symtabix = i;
else
if (!strcmp(name, ".strtab"))
strtabix = i;
else
if (!strcmp(name, ".text") || !strcmp(name, ".rodata"))
symTypeTable[i] = N_TEXT;
else
if (!strcmp(name, ".data") || !strcmp(name, ".sdata") ||
!strcmp(name, ".lit4") || !strcmp(name, ".lit8"))
symTypeTable[i] = N_DATA;
else
if (!strcmp(name, ".bss") || !strcmp(name, ".sbss"))
symTypeTable[i] = N_BSS;
}
/* code assumes these will be found */
if(symtabix == -1 || strtabix == -1) {
fprintf(stderr, "no strings/symbols found\n");
exit(1);
}
/* Figure out if we can cram the program header into an a.out
* header... Basically, we can't handle anything but loadable
* segments, but we can ignore some kinds of segments. We can't
* handle holes in the address space, and we handle start addresses
* other than 0x1000 by hoping that the loader will know where to load
* - a.out doesn't have an explicit load address. Segments may be
* out of order, so we sort them first. */
qsort(ph, ex.e_phnum, sizeof(Elf32_Phdr), phcmp);
for (i = 0; i < ex.e_phnum; i++) {
/* Section types we can ignore... */
if (ph[i].p_type == PT_NULL || ph[i].p_type == PT_NOTE ||
ph[i].p_type == PT_PHDR || ph[i].p_type == PT_MIPS_REGINFO
|| ph[i].p_type == PT_GNU_STACK)
continue;
/* Section types we can't handle... */
else
if (ph[i].p_type != PT_LOAD)
errx(1, "Program header %d type %d can't be converted.", i, ph[i].p_type);
/* Writable (data) segment? */
if (ph[i].p_flags & PF_W) {
struct sect ndata, nbss;
ndata.vaddr = ph[i].p_vaddr;
ndata.len = ph[i].p_filesz;
nbss.vaddr = ph[i].p_vaddr + ph[i].p_filesz;
nbss.len = ph[i].p_memsz - ph[i].p_filesz;
combine(&data, &ndata, 0);
combine(&bss, &nbss, 1);
} else {
struct sect ntxt;
ntxt.vaddr = ph[i].p_vaddr;
ntxt.len = ph[i].p_filesz;
combine(&text, &ntxt, 0);
}
/* Remember the lowest segment start address. */
if (ph[i].p_vaddr < cur_vma)
cur_vma = ph[i].p_vaddr;
}
/* Sections must be in order to be converted... */
if (text.vaddr > data.vaddr || data.vaddr > bss.vaddr ||
text.vaddr + text.len > data.vaddr || data.vaddr + data.len > bss.vaddr) {
fprintf(stderr, "Sections ordering prevents a.out conversion.\n");
exit(1);
}
/* If there's a data section but no text section, then the loader
* combined everything into one section. That needs to be the text
* section, so just make the data section zero length following text. */
if (data.len && !text.len) {
text = data;
data.vaddr = text.vaddr + text.len;
data.len = 0;
}
/* If there is a gap between text and data, we'll fill it when we copy
* the data, so update the length of the text segment as represented
* in a.out to reflect that, since a.out doesn't allow gaps in the
* program address space. */
if (text.vaddr + text.len < data.vaddr)
text.len = data.vaddr - text.vaddr;
/* We now have enough information to cons up an a.out header... */
#ifndef __minix
aex.a_midmag = htonl((symflag << 26) | (MID_PMAX << 16) | OMAGIC);
if (ex.e_machine == EM_PPC)
aex.a_midmag = htonl((symflag << 26) | (MID_POWERPC << 16)
| OMAGIC);
#endif
#ifdef __minix
aex.a_hdrlen = sizeof(struct exec);
aex.a_magic[0] = A_MAGIC0;
aex.a_magic[1] = A_MAGIC1;
aex.a_cpu = A_I80386;
aex.a_flags = A_NSYM | A_EXEC;
aex.a_unused = 0;
aex.a_version = 0;
/* total adds an implicit stack limit */
aex.a_total = aex.a_text + aex.a_data + aex.a_bss + 20 * 1024 * 1024;
#endif
aex.a_text = text.len;
aex.a_data = data.len;
aex.a_bss = bss.len;
aex.a_entry = ex.e_entry;
aex.a_syms = (sizeof(struct nlist) *
(symtabix != -1
? sh[symtabix].sh_size / sizeof(Elf32_Sym) : 0));
aex.a_trsize = 0;
aex.a_drsize = 0;
/* Make the output file... */
if ((outfile = open(argv[2], O_WRONLY | O_CREAT, 0777)) < 0) {
fprintf(stderr, "Unable to create %s: %s\n", argv[2], strerror(errno));
exit(1);
}
/* Truncate file... */
if (ftruncate(outfile, 0)) {
warn("ftruncate %s", argv[2]);
}
/* Write the header... */
i = write(outfile, &aex, sizeof aex);
if (i != sizeof aex) {
perror("aex: write");
exit(1);
}
/* Copy the loadable sections. Zero-fill any gaps less than 64k;
* complain about any zero-filling, and die if we're asked to
* zero-fill more than 64k. */
for (i = 0; i < ex.e_phnum; i++) {
/* Unprocessable sections were handled above, so just verify
* that the section can be loaded before copying. */
if (ph[i].p_type == PT_LOAD && ph[i].p_filesz) {
if (cur_vma != ph[i].p_vaddr) {
unsigned long gap = ph[i].p_vaddr - cur_vma;
char obuf[1024];
if (gap > 65536)
errx(1,
"Intersegment gap (%ld bytes) too large.", (long) gap);
#ifdef DEBUG
warnx("Warning: %ld byte intersegment gap.",
(long)gap);
#endif
memset(obuf, 0, sizeof obuf);
while (gap) {
int count = write(outfile, obuf, (gap > sizeof obuf
? sizeof obuf : gap));
if (count < 0) {
fprintf(stderr, "Error writing gap: %s\n",
strerror(errno));
exit(1);
}
gap -= count;
}
}
copy(outfile, infile, ph[i].p_offset, ph[i].p_filesz);
cur_vma = ph[i].p_vaddr + ph[i].p_filesz;
}
}
/* Copy and translate the symbol table... */
translate_syms(outfile, infile,
sh[symtabix].sh_offset, sh[symtabix].sh_size,
sh[strtabix].sh_offset, sh[strtabix].sh_size);
/* Looks like we won... */
exit(0);
}
/* translate_syms (out, in, offset, size)
Read the ELF symbol table from in at offset; translate it into a.out
nlist format and write it to out. */
void
translate_syms(out, in, symoff, symsize, stroff, strsize)
int out, in;
off_t symoff, symsize;
off_t stroff, strsize;
{
#define SYMS_PER_PASS 64
Elf32_Sym inbuf[64];
struct nlist outbuf[64];
int i, remaining, cur;
char *oldstrings;
char *newstrings, *nsp;
int newstringsize, rem;
/* Zero the unused fields in the output buffer.. */
memset(outbuf, 0, sizeof outbuf);
/* Find number of symbols to process... */
remaining = symsize / sizeof(Elf32_Sym);
/* Suck in the old string table... */
oldstrings = saveRead(in, stroff, strsize, "string table");
/* Allocate space for the new one. XXX We make the wild assumption
* that no two symbol table entries will point at the same place in
* the string table - if that assumption is bad, this could easily
* blow up. */
rem = newstringsize = strsize + remaining;
newstrings = (char *) malloc(newstringsize);
if (!newstrings) {
fprintf(stderr, "No memory for new string table!\n");
exit(1);
}
/* Initialize the table pointer... */
nsp = newstrings;
/* Go the start of the ELF symbol table... */
if (lseek(in, symoff, SEEK_SET) < 0) {
perror("translate_syms: lseek");
exit(1);
}
/* Translate and copy symbols... */
while (remaining) {
cur = remaining;
if (cur > SYMS_PER_PASS)
cur = SYMS_PER_PASS;
remaining -= cur;
if ((i = read(in, inbuf, cur * sizeof(Elf32_Sym)))
!= cur * sizeof(Elf32_Sym)) {
if (i < 0)
perror("translate_syms");
else
fprintf(stderr, "translate_syms: premature end of file.\n");
exit(1);
}
/* Do the translation... */
for (i = 0; i < cur; i++) {
int binding, type, m = sizeof(outbuf[i].n_name);
int n;
char *nn;
/* Copy the symbol into the new table, but prepend an
* underscore. */
n = 1 + strlen(nsp+1);
if(rem < n) {
fprintf(stderr, "only %d remain.\n", rem);
exit(1);
}
*nsp = '_';
nn = nsp+1;
strcpy(nsp + 1, oldstrings + inbuf[i].st_name);
#ifndef __minix
outbuf[i].n_un.n_strx = nsp - newstrings + 4;
#else
strncpy(outbuf[i].n_name, nn, m);
outbuf[i].n_name[m-1] = '\0';
#endif
nsp += n;
rem -= n;
type = ELF32_ST_TYPE(inbuf[i].st_info);
binding = ELF32_ST_BIND(inbuf[i].st_info);
/* Convert ELF symbol type/section/etc info into a.out
* type info. */
if (type == STT_FILE)
#ifdef N_FN
outbuf[i].n_type = N_FN;
#else
outbuf[i].n_type = N_UNDF;
#endif
else
if (inbuf[i].st_shndx == SHN_UNDEF)
outbuf[i].n_type = N_UNDF;
else
if (inbuf[i].st_shndx == SHN_ABS)
outbuf[i].n_type = N_ABS;
else
if (inbuf[i].st_shndx == SHN_COMMON ||
inbuf[i].st_shndx == SHN_MIPS_ACOMMON)
outbuf[i].n_type = N_COMM;
else
outbuf[i].n_type = symTypeTable[inbuf[i].st_shndx];
#ifdef N_EXT
if (binding == STB_GLOBAL)
outbuf[i].n_type |= N_EXT;
#endif
/* Symbol values in executables should be compatible. */
outbuf[i].n_value = inbuf[i].st_value;
}
/* Write out the symbols... */
if ((i = write(out, outbuf, cur * sizeof(struct nlist)))
!= cur * sizeof(struct nlist)) {
fprintf(stderr, "translate_syms: write: %s\n", strerror(errno));
exit(1);
}
}
/* Write out the string table length... */
if (write(out, &newstringsize, sizeof newstringsize)
!= sizeof newstringsize) {
fprintf(stderr,
"translate_syms: newstringsize: %s\n", strerror(errno));
exit(1);
}
/* Write out the string table... */
if (write(out, newstrings, newstringsize) != newstringsize) {
fprintf(stderr, "translate_syms: newstrings: %s\n", strerror(errno));
exit(1);
}
}
void
copy(out, in, offset, size)
int out, in;
off_t offset, size;
{
char ibuf[4096];
int remaining, cur, count;
/* Go to the start of the ELF symbol table... */
if (lseek(in, offset, SEEK_SET) < 0) {
perror("copy: lseek");
exit(1);
}
remaining = size;
while (remaining) {
cur = remaining;
if (cur > sizeof ibuf)
cur = sizeof ibuf;
remaining -= cur;
if ((count = read(in, ibuf, cur)) != cur) {
fprintf(stderr, "copy: read: %s\n",
count ? strerror(errno) : "premature end of file");
exit(1);
}
if ((count = write(out, ibuf, cur)) != cur) {
perror("copy: write");
exit(1);
}
}
}
/* Combine two segments, which must be contiguous. If pad is true, it's
okay for there to be padding between. */
void
combine(base, new, pad)
struct sect *base, *new;
int pad;
{
if (!base->len)
*base = *new;
else
if (new->len) {
if (base->vaddr + base->len != new->vaddr) {
if (pad)
base->len = new->vaddr - base->vaddr;
else {
fprintf(stderr,
"Non-contiguous data can't be converted.\n");
exit(1);
}
}
base->len += new->len;
}
}
int
phcmp(vh1, vh2)
const void *vh1, *vh2;
{
Elf32_Phdr *h1, *h2;
h1 = (Elf32_Phdr *) vh1;
h2 = (Elf32_Phdr *) vh2;
if (h1->p_vaddr > h2->p_vaddr)
return 1;
else
if (h1->p_vaddr < h2->p_vaddr)
return -1;
else
return 0;
}
char *
saveRead(int file, off_t offset, off_t len, char *name)
{
char *tmp;
int count;
off_t off;
if ((off = lseek(file, offset, SEEK_SET)) < 0) {
fprintf(stderr, "%s: fseek: %s\n", name, strerror(errno));
exit(1);
}
if (!(tmp = (char *) malloc(len)))
errx(1, "%s: Can't allocate %ld bytes.", name, (long)len);
count = read(file, tmp, len);
if (count != len) {
fprintf(stderr, "%s: read: %s.\n",
name, count ? strerror(errno) : "End of file reached");
exit(1);
}
return tmp;
}

View file

@ -0,0 +1,35 @@
/* $NetBSD: elf_machdep.h,v 1.9 2001/12/09 23:05:57 thorpej Exp $ */
#define ELF32_MACHDEP_ENDIANNESS ELFDATA2LSB
#define ELF32_MACHDEP_ID_CASES \
case EM_386: \
case EM_486: \
break;
#define ELF64_MACHDEP_ENDIANNESS XXX /* break compilation */
#define ELF64_MACHDEP_ID_CASES \
/* no 64-bit ELF machine types supported */
#define ELF32_MACHDEP_ID EM_386
#define ARCH_ELFSIZE 32 /* MD native binary size */
/* i386 relocations */
#define R_386_NONE 0
#define R_386_32 1
#define R_386_PC32 2
#define R_386_GOT32 3
#define R_386_PLT32 4
#define R_386_COPY 5
#define R_386_GLOB_DAT 6
#define R_386_JMP_SLOT 7
#define R_386_RELATIVE 8
#define R_386_GOTOFF 9
#define R_386_GOTPC 10
/* The following relocations are GNU extensions. */
#define R_386_16 20
#define R_386_PC16 21
#define R_386_8 22
#define R_386_PC8 23
#define R_TYPE(name) __CONCAT(R_386_,name)

View file

@ -0,0 +1,948 @@
/* $NetBSD: exec_elf.h,v 1.95 2008/04/28 20:24:10 martin Exp $ */
/*-
* Copyright (c) 1994 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_EXEC_ELF_H_
#define _SYS_EXEC_ELF_H_
/*
* The current ELF ABI specification is available at:
* http://www.sco.com/developers/gabi/
*
* Current header definitions are in:
* http://www.sco.com/developers/gabi/latest/ch4.eheader.html
*/
#if defined(_KERNEL) || defined(_STANDALONE)
#include <sys/types.h>
#else
#include <inttypes.h>
#endif /* _KERNEL || _STANDALONE */
#if defined(ELFSIZE)
#define CONCAT(x,y) __CONCAT(x,y)
#define ELFNAME(x) CONCAT(elf,CONCAT(ELFSIZE,CONCAT(_,x)))
#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y))))
#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE))
#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x)))
#endif
#if HAVE_NBTOOL_CONFIG_H
#include <nbinclude/machine/elf_machdep.h>
#else
#include "elf_machdep.h"
#endif
typedef uint8_t Elf_Byte;
typedef uint32_t Elf32_Addr;
#define ELF32_FSZ_ADDR 4
typedef uint32_t Elf32_Off;
#define ELF32_FSZ_OFF 4
typedef int32_t Elf32_Sword;
#define ELF32_FSZ_SWORD 4
typedef uint32_t Elf32_Word;
#define ELF32_FSZ_WORD 4
typedef uint16_t Elf32_Half;
#define ELF32_FSZ_HALF 2
typedef uint64_t Elf64_Addr;
#define ELF64_FSZ_ADDR 8
typedef uint64_t Elf64_Off;
#define ELF64_FSZ_OFF 8
typedef int32_t Elf64_Shalf;
#define ELF64_FSZ_SHALF 4
#ifndef ELF64_FSZ_SWORD
typedef int32_t Elf64_Sword;
#define ELF64_FSZ_SWORD 4
#endif /* ELF64_FSZ_SWORD */
#ifndef ELF64_FSZ_WORD
typedef uint32_t Elf64_Word;
#define ELF64_FSZ_WORD 4
#endif /* ELF64_FSZ_WORD */
typedef int64_t Elf64_Sxword;
#define ELF64_FSZ_XWORD 8
typedef uint64_t Elf64_Xword;
#define ELF64_FSZ_XWORD 8
typedef uint32_t Elf64_Half;
#define ELF64_FSZ_HALF 4
typedef uint16_t Elf64_Quarter;
#define ELF64_FSZ_QUARTER 2
/*
* ELF Header
*/
#define ELF_NIDENT 16
typedef struct {
unsigned char e_ident[ELF_NIDENT]; /* Id bytes */
Elf32_Half e_type; /* file type */
Elf32_Half e_machine; /* machine type */
Elf32_Word e_version; /* version number */
Elf32_Addr e_entry; /* entry point */
Elf32_Off e_phoff; /* Program hdr offset */
Elf32_Off e_shoff; /* Section hdr offset */
Elf32_Word e_flags; /* Processor flags */
Elf32_Half e_ehsize; /* sizeof ehdr */
Elf32_Half e_phentsize; /* Program header entry size */
Elf32_Half e_phnum; /* Number of program headers */
Elf32_Half e_shentsize; /* Section header entry size */
Elf32_Half e_shnum; /* Number of section headers */
Elf32_Half e_shstrndx; /* String table index */
} Elf32_Ehdr;
typedef struct {
unsigned char e_ident[ELF_NIDENT]; /* Id bytes */
Elf64_Quarter e_type; /* file type */
Elf64_Quarter e_machine; /* machine type */
Elf64_Half e_version; /* version number */
Elf64_Addr e_entry; /* entry point */
Elf64_Off e_phoff; /* Program hdr offset */
Elf64_Off e_shoff; /* Section hdr offset */
Elf64_Half e_flags; /* Processor flags */
Elf64_Quarter e_ehsize; /* sizeof ehdr */
Elf64_Quarter e_phentsize; /* Program header entry size */
Elf64_Quarter e_phnum; /* Number of program headers */
Elf64_Quarter e_shentsize; /* Section header entry size */
Elf64_Quarter e_shnum; /* Number of section headers */
Elf64_Quarter e_shstrndx; /* String table index */
} Elf64_Ehdr;
/* e_ident offsets */
#define EI_MAG0 0 /* '\177' */
#define EI_MAG1 1 /* 'E' */
#define EI_MAG2 2 /* 'L' */
#define EI_MAG3 3 /* 'F' */
#define EI_CLASS 4 /* File class */
#define EI_DATA 5 /* Data encoding */
#define EI_VERSION 6 /* File version */
#define EI_OSABI 7 /* Operating system/ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define EI_PAD 9 /* Start of padding bytes up to EI_NIDENT*/
#define EI_NIDENT 16 /* First non-ident header byte */
/* e_ident[EI_MAG0,EI_MAG3] */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF"
#define SELFMAG 4
/* e_ident[EI_CLASS] */
#define ELFCLASSNONE 0 /* Invalid class */
#define ELFCLASS32 1 /* 32-bit objects */
#define ELFCLASS64 2 /* 64-bit objects */
#define ELFCLASSNUM 3
/* e_ident[EI_DATA] */
#define ELFDATANONE 0 /* Invalid data encoding */
#define ELFDATA2LSB 1 /* 2's complement values, LSB first */
#define ELFDATA2MSB 2 /* 2's complement values, MSB first */
/* e_ident[EI_VERSION] */
#define EV_NONE 0 /* Invalid version */
#define EV_CURRENT 1 /* Current version */
#define EV_NUM 2
/* e_ident[EI_OSABI] */
#define ELFOSABI_SYSV 0 /* UNIX System V ABI */
#define ELFOSABI_HPUX 1 /* HP-UX operating system */
#define ELFOSABI_NETBSD 2 /* NetBSD */
#define ELFOSABI_LINUX 3 /* GNU/Linux */
#define ELFOSABI_HURD 4 /* GNU/Hurd */
#define ELFOSABI_86OPEN 5 /* 86Open */
#define ELFOSABI_SOLARIS 6 /* Solaris */
#define ELFOSABI_MONTEREY 7 /* Monterey */
#define ELFOSABI_IRIX 8 /* IRIX */
#define ELFOSABI_FREEBSD 9 /* FreeBSD */
#define ELFOSABI_TRU64 10 /* TRU64 UNIX */
#define ELFOSABI_MODESTO 11 /* Novell Modesto */
#define ELFOSABI_OPENBSD 12 /* OpenBSD */
/* Unofficial OSABIs follow */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
/* e_type */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* Relocatable file */
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_NUM 5
#define ET_LOOS 0xfe00 /* Operating system specific range */
#define ET_HIOS 0xfeff
#define ET_LOPROC 0xff00 /* Processor-specific range */
#define ET_HIPROC 0xffff
/* e_machine */
#define EM_NONE 0 /* No machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola 68000 */
#define EM_88K 5 /* Motorola 88000 */
#define EM_486 6 /* Intel 80486 */
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS I Architecture */
#define EM_S370 9 /* Amdahl UTS on System/370 */
#define EM_MIPS_RS3_LE 10 /* MIPS RS3000 Little-endian */
/* 11-14 - Reserved */
#define EM_RS6000 11 /* IBM RS/6000 XXX reserved */
#define EM_PARISC 15 /* Hewlett-Packard PA-RISC */
#define EM_NCUBE 16 /* NCube XXX reserved */
#define EM_VPP500 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Enhanced instruction set SPARC */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
/* 22-35 - Reserved */
#define EM_V800 36 /* NEC V800 */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH-32 */
#define EM_RCE 39 /* Motorola RCE */
#define EM_ARM 40 /* Advanced RISC Machines ARM */
#define EM_ALPHA 41 /* DIGITAL Alpha */
#define EM_SH 42 /* Hitachi Super-H */
#define EM_SPARCV9 43 /* SPARC Version 9 */
#define EM_TRICORE 44 /* Siemens Tricore */
#define EM_ARC 45 /* Argonaut RISC Core */
#define EM_H8_300 46 /* Hitachi H8/300 */
#define EM_H8_300H 47 /* Hitachi H8/300H */
#define EM_H8S 48 /* Hitachi H8S */
#define EM_H8_500 49 /* Hitachi H8/500 */
#define EM_IA_64 50 /* Intel Merced Processor */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola MC68HC12 */
#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator */
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Star*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronics ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded family processor */
#define EM_X86_64 62 /* AMD x86-64 architecture */
#define EM_PDSP 63 /* Sony DSP Processor */
#define EM_PDP10 64 /* Digital Equipment Corp. PDP-10 */
#define EM_PDP11 65 /* Digital Equipment Corp. PDP-11 */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */
#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8-bit CPU */
#define EM_VAX 75 /* Digital VAX */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded CPU */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP processor */
#define EM_ZSP 79 /* LSI Logic's 16-bit DSP processor */
#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
#define EM_HUANY 81 /* Harvard's machine-independent format */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi D10V */
#define EM_D30V 86 /* Mitsubishi D30V */
#define EM_V850 87 /* NEC v850 */
#define EM_M32R 88 /* Mitsubishi M32R */
#define EM_MN10300 89 /* Matsushita MN10300 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
#define EM_NS32K 97 /* National Semiconductor 32000 series */
/* Unofficial machine types follow */
#define EM_AVR32 6317 /* used by NetBSD/avr32 */
#define EM_ALPHA_EXP 36902 /* used by NetBSD/alpha; obsolete */
#define EM_NUM 36903
/*
* Program Header
*/
typedef struct {
Elf32_Word p_type; /* entry type */
Elf32_Off p_offset; /* offset */
Elf32_Addr p_vaddr; /* virtual address */
Elf32_Addr p_paddr; /* physical address */
Elf32_Word p_filesz; /* file size */
Elf32_Word p_memsz; /* memory size */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory & file alignment */
} Elf32_Phdr;
typedef struct {
Elf64_Half p_type; /* entry type */
Elf64_Half p_flags; /* flags */
Elf64_Off p_offset; /* offset */
Elf64_Addr p_vaddr; /* virtual address */
Elf64_Addr p_paddr; /* physical address */
Elf64_Xword p_filesz; /* file size */
Elf64_Xword p_memsz; /* memory size */
Elf64_Xword p_align; /* memory & file alignment */
} Elf64_Phdr;
/* p_type */
#define PT_NULL 0 /* Program header table entry unused */
#define PT_LOAD 1 /* Loadable program segment */
#define PT_DYNAMIC 2 /* Dynamic linking information */
#define PT_INTERP 3 /* Program interpreter */
#define PT_NOTE 4 /* Auxiliary information */
#define PT_SHLIB 5 /* Reserved, unspecified semantics */
#define PT_PHDR 6 /* Entry for header table itself */
#define PT_NUM 7
#define PT_LOOS 0x60000000 /* OS-specific range */
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000 /* Processor-specific range */
#define PT_HIPROC 0x7fffffff
#define PT_MIPS_REGINFO 0x70000000
#define PT_GNU_STACK 0x6474e551
/* p_flags */
#define PF_R 0x4 /* Segment is readable */
#define PF_W 0x2 /* Segment is writable */
#define PF_X 0x1 /* Segment is executable */
#define PF_MASKOS 0x0ff00000 /* Operating system specific values */
#define PF_MASKPROC 0xf0000000 /* Processor-specific values */
/*
* Section Headers
*/
typedef struct {
Elf32_Word sh_name; /* section name (.shstrtab index) */
Elf32_Word sh_type; /* section type */
Elf32_Word sh_flags; /* section flags */
Elf32_Addr sh_addr; /* virtual address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* link to another */
Elf32_Word sh_info; /* misc info */
Elf32_Word sh_addralign; /* memory alignment */
Elf32_Word sh_entsize; /* table entry size */
} Elf32_Shdr;
typedef struct {
Elf64_Half sh_name; /* section name (.shstrtab index) */
Elf64_Half sh_type; /* section type */
Elf64_Xword sh_flags; /* section flags */
Elf64_Addr sh_addr; /* virtual address */
Elf64_Off sh_offset; /* file offset */
Elf64_Xword sh_size; /* section size */
Elf64_Half sh_link; /* link to another */
Elf64_Half sh_info; /* misc info */
Elf64_Xword sh_addralign; /* memory alignment */
Elf64_Xword sh_entsize; /* table entry size */
} Elf64_Shdr;
/* sh_type */
#define SHT_NULL 0 /* Section header table entry unused */
#define SHT_PROGBITS 1 /* Program information */
#define SHT_SYMTAB 2 /* Symbol table */
#define SHT_STRTAB 3 /* String table */
#define SHT_RELA 4 /* Relocation information w/ addend */
#define SHT_HASH 5 /* Symbol hash table */
#define SHT_DYNAMIC 6 /* Dynamic linking information */
#define SHT_NOTE 7 /* Auxiliary information */
#define SHT_NOBITS 8 /* No space allocated in file image */
#define SHT_REL 9 /* Relocation information w/o addend */
#define SHT_SHLIB 10 /* Reserved, unspecified semantics */
#define SHT_DYNSYM 11 /* Symbol table for dynamic linker */
#define SHT_NUM 12
#define SHT_LOOS 0x60000000 /* Operating system specific range */
#define SHT_SUNW_VERDEF 0x6ffffffd /* Versions defined by file */
#define SHT_SUNW_VERNEED 0x6ffffffe /* Versions needed by file */
#define SHT_SUNW_VERSYM 0x6fffffff /* Symbol versions */
#define SHT_HIOS 0x6fffffff
#define SHT_LOPROC 0x70000000 /* Processor-specific range */
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000 /* Application-specific range */
#define SHT_HIUSER 0xffffffff
/* sh_flags */
#define SHF_WRITE 0x1 /* Section contains writable data */
#define SHF_ALLOC 0x2 /* Section occupies memory */
#define SHF_EXECINSTR 0x4 /* Section contains executable insns */
#define SHF_MASKOS 0x0f000000 /* Operating system specific values */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific values */
/*
* Symbol Table
*/
typedef struct {
Elf32_Word st_name; /* Symbol name (.symtab index) */
Elf32_Word st_value; /* value of symbol */
Elf32_Word st_size; /* size of symbol */
Elf_Byte st_info; /* type / binding attrs */
Elf_Byte st_other; /* unused */
Elf32_Half st_shndx; /* section index of symbol */
} Elf32_Sym;
typedef struct {
Elf64_Half st_name; /* Symbol name (.symtab index) */
Elf_Byte st_info; /* type / binding attrs */
Elf_Byte st_other; /* unused */
Elf64_Quarter st_shndx; /* section index of symbol */
Elf64_Addr st_value; /* value of symbol */
Elf64_Xword st_size; /* size of symbol */
} Elf64_Sym;
/* Symbol Table index of the undefined symbol */
#define ELF_SYM_UNDEFINED 0
#define STN_UNDEF 0 /* undefined index */
/* st_info: Symbol Bindings */
#define STB_LOCAL 0 /* local symbol */
#define STB_GLOBAL 1 /* global symbol */
#define STB_WEAK 2 /* weakly defined global symbol */
#define STB_NUM 3
#define STB_LOOS 10 /* Operating system specific range */
#define STB_HIOS 12
#define STB_LOPROC 13 /* Processor-specific range */
#define STB_HIPROC 15
/* st_info: Symbol Types */
#define STT_NOTYPE 0 /* Type not specified */
#define STT_OBJECT 1 /* Associated with a data object */
#define STT_FUNC 2 /* Associated with a function */
#define STT_SECTION 3 /* Associated with a section */
#define STT_FILE 4 /* Associated with a file name */
#define STT_NUM 5
#define STT_LOOS 10 /* Operating system specific range */
#define STT_HIOS 12
#define STT_LOPROC 13 /* Processor-specific range */
#define STT_HIPROC 15
/* st_other: Visibility Types */
#define STV_DEFAULT 0 /* use binding type */
#define STV_INTERNAL 1 /* not referenced from outside */
#define STV_HIDDEN 2 /* not visible, may be used via ptr */
#define STV_PROTECTED 3 /* visible, not preemptible */
/* st_info/st_other utility macros */
#define ELF_ST_BIND(info) ((uint32_t)(info) >> 4)
#define ELF_ST_TYPE(info) ((uint32_t)(info) & 0xf)
#define ELF_ST_INFO(bind,type) ((Elf_Byte)(((bind) << 4) | \
((type) & 0xf)))
#define ELF_ST_VISIBILITY(other) ((uint32_t)(other) & 3)
/*
* Special section indexes
*/
#define SHN_UNDEF 0 /* Undefined section */
#define SHN_LORESERVE 0xff00 /* Reserved range */
#define SHN_ABS 0xfff1 /* Absolute symbols */
#define SHN_COMMON 0xfff2 /* Common symbols */
#define SHN_HIRESERVE 0xffff
#define SHN_LOPROC 0xff00 /* Processor-specific range */
#define SHN_HIPROC 0xff1f
#define SHN_LOOS 0xff20 /* Operating system specific range */
#define SHN_HIOS 0xff3f
#define SHN_MIPS_ACOMMON 0xff00
#define SHN_MIPS_TEXT 0xff01
#define SHN_MIPS_DATA 0xff02
#define SHN_MIPS_SCOMMON 0xff03
/*
* Relocation Entries
*/
typedef struct {
Elf32_Word r_offset; /* where to do it */
Elf32_Word r_info; /* index & type of relocation */
} Elf32_Rel;
typedef struct {
Elf32_Word r_offset; /* where to do it */
Elf32_Word r_info; /* index & type of relocation */
Elf32_Sword r_addend; /* adjustment value */
} Elf32_Rela;
/* r_info utility macros */
#define ELF32_R_SYM(info) ((info) >> 8)
#define ELF32_R_TYPE(info) ((info) & 0xff)
#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
typedef struct {
Elf64_Addr r_offset; /* where to do it */
Elf64_Xword r_info; /* index & type of relocation */
} Elf64_Rel;
typedef struct {
Elf64_Addr r_offset; /* where to do it */
Elf64_Xword r_info; /* index & type of relocation */
Elf64_Sxword r_addend; /* adjustment value */
} Elf64_Rela;
/* r_info utility macros */
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xffffffff)
#define ELF64_R_INFO(sym,type) (((sym) << 32) + (type))
/*
* Dynamic Section structure array
*/
typedef struct {
Elf32_Word d_tag; /* entry tag value */
union {
Elf32_Addr d_ptr;
Elf32_Word d_val;
} d_un;
} Elf32_Dyn;
typedef struct {
Elf64_Xword d_tag; /* entry tag value */
union {
Elf64_Addr d_ptr;
Elf64_Xword d_val;
} d_un;
} Elf64_Dyn;
/* d_tag */
#define DT_NULL 0 /* Marks end of dynamic array */
#define DT_NEEDED 1 /* Name of needed library (DT_STRTAB offset) */
#define DT_PLTRELSZ 2 /* Size, in bytes, of relocations in PLT */
#define DT_PLTGOT 3 /* Address of PLT and/or GOT */
#define DT_HASH 4 /* Address of symbol hash table */
#define DT_STRTAB 5 /* Address of string table */
#define DT_SYMTAB 6 /* Address of symbol table */
#define DT_RELA 7 /* Address of Rela relocation table */
#define DT_RELASZ 8 /* Size, in bytes, of DT_RELA table */
#define DT_RELAENT 9 /* Size, in bytes, of one DT_RELA entry */
#define DT_STRSZ 10 /* Size, in bytes, of DT_STRTAB table */
#define DT_SYMENT 11 /* Size, in bytes, of one DT_SYMTAB entry */
#define DT_INIT 12 /* Address of initialization function */
#define DT_FINI 13 /* Address of termination function */
#define DT_SONAME 14 /* Shared object name (DT_STRTAB offset) */
#define DT_RPATH 15 /* Library search path (DT_STRTAB offset) */
#define DT_SYMBOLIC 16 /* Start symbol search within local object */
#define DT_REL 17 /* Address of Rel relocation table */
#define DT_RELSZ 18 /* Size, in bytes, of DT_REL table */
#define DT_RELENT 19 /* Size, in bytes, of one DT_REL entry */
#define DT_PLTREL 20 /* Type of PLT relocation entries */
#define DT_DEBUG 21 /* Used for debugging; unspecified */
#define DT_TEXTREL 22 /* Relocations might modify non-writable seg */
#define DT_JMPREL 23 /* Address of relocations associated with PLT */
#define DT_BIND_NOW 24 /* Process all relocations at load-time */
#define DT_INIT_ARRAY 25 /* Address of initialization function array */
#define DT_FINI_ARRAY 26 /* Size, in bytes, of DT_INIT_ARRAY array */
#define DT_INIT_ARRAYSZ 27 /* Address of termination function array */
#define DT_FINI_ARRAYSZ 28 /* Size, in bytes, of DT_FINI_ARRAY array*/
#define DT_NUM 29
#define DT_LOOS 0x60000000 /* Operating system specific range */
#define DT_VERSYM 0x6ffffff0 /* Symbol versions */
#define DT_FLAGS_1 0x6ffffffb /* ELF dynamic flags */
#define DT_VERDEF 0x6ffffffc /* Versions defined by file */
#define DT_VERDEFNUM 0x6ffffffd /* Number of versions defined by file */
#define DT_VERNEED 0x6ffffffe /* Versions needed by file */
#define DT_VERNEEDNUM 0x6fffffff /* Number of versions needed by file */
#define DT_HIOS 0x6fffffff
#define DT_LOPROC 0x70000000 /* Processor-specific range */
#define DT_HIPROC 0x7fffffff
/* Flag values for DT_FLAGS_1 (incomplete) */
#define DF_1_INITFIRST 0x00000020 /* Object's init/fini take priority */
/*
* Auxiliary Vectors
*/
typedef struct {
Elf32_Word a_type; /* 32-bit id */
Elf32_Word a_v; /* 32-bit id */
} Aux32Info;
typedef struct {
Elf64_Half a_type; /* 32-bit id */
Elf64_Xword a_v; /* 64-bit id */
} Aux64Info;
/* a_type */
#define AT_NULL 0 /* Marks end of array */
#define AT_IGNORE 1 /* No meaning, a_un is undefined */
#define AT_EXECFD 2 /* Open file descriptor of object file */
#define AT_PHDR 3 /* &phdr[0] */
#define AT_PHENT 4 /* sizeof(phdr[0]) */
#define AT_PHNUM 5 /* # phdr entries */
#define AT_PAGESZ 6 /* PAGESIZE */
#define AT_BASE 7 /* Interpreter base addr */
#define AT_FLAGS 8 /* Processor flags */
#define AT_ENTRY 9 /* Entry address of executable */
#define AT_DCACHEBSIZE 10 /* Data cache block size */
#define AT_ICACHEBSIZE 11 /* Instruction cache block size */
#define AT_UCACHEBSIZE 12 /* Unified cache block size */
/* Vendor specific */
#define AT_MIPS_NOTELF 10 /* XXX a_val != 0 -> MIPS XCOFF executable */
#define AT_EUID 2000 /* euid (solaris compatible numbers) */
#define AT_RUID 2001 /* ruid (solaris compatible numbers) */
#define AT_EGID 2002 /* egid (solaris compatible numbers) */
#define AT_RGID 2003 /* rgid (solaris compatible numbers) */
/* Solaris kernel specific */
#define AT_SUN_LDELF 2004 /* dynamic linker's ELF header */
#define AT_SUN_LDSHDR 2005 /* dynamic linker's section header */
#define AT_SUN_LDNAME 2006 /* dynamic linker's name */
#define AT_SUN_LPGSIZE 2007 /* large pagesize */
/* Other information */
#define AT_SUN_PLATFORM 2008 /* sysinfo(SI_PLATFORM) */
#define AT_SUN_HWCAP 2009 /* process hardware capabilities */
#define AT_SUN_IFLUSH 2010 /* do we need to flush the instruction cache? */
#define AT_SUN_CPU 2011 /* CPU name */
/* ibcs2 emulation band aid */
#define AT_SUN_EMUL_ENTRY 2012 /* coff entry point */
#define AT_SUN_EMUL_EXECFD 2013 /* coff file descriptor */
/* Executable's fully resolved name */
#define AT_SUN_EXECNAME 2014
/*
* Note Headers
*/
typedef struct {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
Elf32_Word n_type;
} Elf32_Nhdr;
typedef struct {
Elf64_Half n_namesz;
Elf64_Half n_descsz;
Elf64_Half n_type;
} Elf64_Nhdr;
#define ELF_NOTE_TYPE_ABI_TAG 1
/* GNU-specific note name and description sizes */
#define ELF_NOTE_ABI_NAMESZ 4
#define ELF_NOTE_ABI_DESCSZ 16
/* GNU-specific note name */
#define ELF_NOTE_ABI_NAME "GNU\0"
/* GNU-specific OS/version value stuff */
#define ELF_NOTE_ABI_OS_LINUX 0
#define ELF_NOTE_ABI_OS_HURD 1
#define ELF_NOTE_ABI_OS_SOLARIS 2
/* NetBSD-specific note type: Emulation name. desc is emul name string. */
#define ELF_NOTE_TYPE_NETBSD_TAG 1
/* NetBSD-specific note name and description sizes */
#define ELF_NOTE_NETBSD_NAMESZ 7
#define ELF_NOTE_NETBSD_DESCSZ 4
/* NetBSD-specific note name */
#define ELF_NOTE_NETBSD_NAME "NetBSD\0\0"
/* NetBSD-specific note type: Checksum. There should be 1 NOTE per PT_LOAD
section. desc is a tuple of <phnum>(16),<chk-type>(16),<chk-value>. */
#define ELF_NOTE_TYPE_CHECKSUM_TAG 2
#define ELF_NOTE_CHECKSUM_CRC32 1
#define ELF_NOTE_CHECKSUM_MD5 2
#define ELF_NOTE_CHECKSUM_SHA1 3
#define ELF_NOTE_CHECKSUM_SHA256 4
/* NetBSD-specific note type: PaX. There should be 1 NOTE per executable.
section. desc is a 32 bit bitmask */
#define ELF_NOTE_TYPE_PAX_TAG 3
#define ELF_NOTE_PAX_MPROTECT 0x01 /* Force enable Mprotect */
#define ELF_NOTE_PAX_NOMPROTECT 0x02 /* Force disable Mprotect */
#define ELF_NOTE_PAX_GUARD 0x04 /* Force enable Segvguard */
#define ELF_NOTE_PAX_NOGUARD 0x08 /* Force disable Servguard */
#define ELF_NOTE_PAX_ASLR 0x10 /* Force enable ASLR */
#define ELF_NOTE_PAX_NOASLR 0x20 /* Force disable ASLR */
#define ELF_NOTE_PAX_NAMESZ 4
#define ELF_NOTE_PAX_NAME "PaX\0"
#define ELF_NOTE_PAX_DESCSZ 4
/*
* NetBSD-specific core file information.
*
* NetBSD ELF core files use notes to provide information about
* the process's state. The note name is "NetBSD-CORE" for
* information that is global to the process, and "NetBSD-CORE@nn",
* where "nn" is the lwpid of the LWP that the information belongs
* to (such as register state).
*
* We use the following note identifiers:
*
* ELF_NOTE_NETBSD_CORE_PROCINFO
* Note is a "netbsd_elfcore_procinfo" structure.
*
* We also use ptrace(2) request numbers (the ones that exist in
* machine-dependent space) to identify register info notes. The
* info in such notes is in the same format that ptrace(2) would
* export that information.
*
* Please try to keep the members of this structure nicely aligned,
* and if you add elements, add them to the end and bump the version.
*/
#define ELF_NOTE_NETBSD_CORE_NAME "NetBSD-CORE"
#define ELF_NOTE_NETBSD_CORE_PROCINFO 1
#define NETBSD_ELFCORE_PROCINFO_VERSION 1
struct netbsd_elfcore_procinfo {
/* Version 1 fields start here. */
uint32_t cpi_version; /* netbsd_elfcore_procinfo version */
uint32_t cpi_cpisize; /* sizeof(netbsd_elfcore_procinfo) */
uint32_t cpi_signo; /* killing signal */
uint32_t cpi_sigcode; /* signal code */
uint32_t cpi_sigpend[4]; /* pending signals */
uint32_t cpi_sigmask[4]; /* blocked signals */
uint32_t cpi_sigignore[4];/* blocked signals */
uint32_t cpi_sigcatch[4];/* blocked signals */
int32_t cpi_pid; /* process ID */
int32_t cpi_ppid; /* parent process ID */
int32_t cpi_pgrp; /* process group ID */
int32_t cpi_sid; /* session ID */
uint32_t cpi_ruid; /* real user ID */
uint32_t cpi_euid; /* effective user ID */
uint32_t cpi_svuid; /* saved user ID */
uint32_t cpi_rgid; /* real group ID */
uint32_t cpi_egid; /* effective group ID */
uint32_t cpi_svgid; /* saved group ID */
uint32_t cpi_nlwps; /* number of LWPs */
int8_t cpi_name[32]; /* copy of p->p_comm */
/* Add version 2 fields below here. */
int32_t cpi_siglwp; /* LWP target of killing signal */
};
#if defined(ELFSIZE) && (ELFSIZE == 32)
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Phdr Elf32_Phdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define Elf_Rel Elf32_Rel
#define Elf_Rela Elf32_Rela
#define Elf_Dyn Elf32_Dyn
#define Elf_Word Elf32_Word
#define Elf_Sword Elf32_Sword
#define Elf_Addr Elf32_Addr
#define Elf_Off Elf32_Off
#define Elf_Nhdr Elf32_Nhdr
#define ELF_R_SYM ELF32_R_SYM
#define ELF_R_TYPE ELF32_R_TYPE
#define ELFCLASS ELFCLASS32
#define AuxInfo Aux32Info
#elif defined(ELFSIZE) && (ELFSIZE == 64)
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Phdr Elf64_Phdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define Elf_Rel Elf64_Rel
#define Elf_Rela Elf64_Rela
#define Elf_Dyn Elf64_Dyn
#define Elf_Word Elf64_Word
#define Elf_Sword Elf64_Sword
#define Elf_Addr Elf64_Addr
#define Elf_Off Elf64_Off
#define Elf_Nhdr Elf64_Nhdr
#define ELF_R_SYM ELF64_R_SYM
#define ELF_R_TYPE ELF64_R_TYPE
#define ELFCLASS ELFCLASS64
#define AuxInfo Aux64Info
#endif
#define ELF32_ST_BIND(info) ELF_ST_BIND(info)
#define ELF32_ST_TYPE(info) ELF_ST_TYPE(info)
#define ELF32_ST_INFO(bind,type) ELF_ST_INFO(bind,type)
#define ELF32_ST_VISIBILITY(other) ELF_ST_VISIBILITY(other)
#define ELF64_ST_BIND(info) ELF_ST_BIND(info)
#define ELF64_ST_TYPE(info) ELF_ST_TYPE(info)
#define ELF64_ST_INFO(bind,type) ELF_ST_INFO(bind,type)
#define ELF64_ST_VISIBILITY(other) ELF_ST_VISIBILITY(other)
#ifdef _KERNEL
#define ELF_AUX_ENTRIES 14 /* Max size of aux array passed to loader */
#define ELF32_NO_ADDR (~(Elf32_Addr)0) /* Indicates addr. not yet filled in */
#define ELF32_LINK_ADDR ((Elf32_Addr)-2) /* advises to use link address */
#define ELF64_NO_ADDR (~(Elf64_Addr)0) /* Indicates addr. not yet filled in */
#define ELF64_LINK_ADDR ((Elf64_Addr)-2) /* advises to use link address */
#if defined(ELFSIZE) && (ELFSIZE == 64)
#define ELF_NO_ADDR ELF64_NO_ADDR
#define ELF_LINK_ADDR ELF64_LINK_ADDR
#elif defined(ELFSIZE) && (ELFSIZE == 32)
#define ELF_NO_ADDR ELF32_NO_ADDR
#define ELF_LINK_ADDR ELF32_LINK_ADDR
#endif
#ifndef ELF32_EHDR_FLAGS_OK
#define ELF32_EHDR_FLAGS_OK(eh) 1
#endif
#ifndef ELF64_EHDR_FLAGS_OK
#define ELF64_EHDR_FLAGS_OK(eh) 1
#endif
#if defined(ELFSIZE) && (ELFSIZE == 64)
#define ELF_EHDR_FLAGS_OK(eh) ELF64_EHDR_FLAGS_OK(eh)
#else
#define ELF_EHDR_FLAGS_OK(eh) ELF32_EHDR_FLAGS_OK(eh)
#endif
#if defined(ELFSIZE)
struct elf_args {
Elf_Addr arg_entry; /* program entry point */
Elf_Addr arg_interp; /* Interpreter load address */
Elf_Addr arg_phaddr; /* program header address */
Elf_Addr arg_phentsize; /* Size of program header */
Elf_Addr arg_phnum; /* Number of program headers */
};
#endif
/*
* These constants are used for Elf32_Verdef struct's version number.
*/
#define VER_DEF_NONE 0
#define VER_DEF_CURRENT 1
/*
* These constants are used for Elf32_Verdef struct's vd_flags.
*/
#define VER_FLG_BASE 0x1
#define VER_FLG_WEAK 0x2
/*
* These are used in an Elf32_Versym field.
*/
#define VER_NDX_LOCAL 0
#define VER_NDX_GLOBAL 1
/*
* These constants are used for Elf32_Verneed struct's version number.
*/
#define VER_NEED_NONE 0
#define VER_NEED_CURRENT 1
/*
* GNU Extension hidding symb
*/
#define VERSYM_HIDDEN 0x8000
#define VERSYM_VERSION 0x7fff
#define ELF_VER_CHR '@'
/*
* These are current size independent.
*/
typedef struct {
Elf32_Half vd_version; /* version number of structure */
Elf32_Half vd_flags; /* flags (VER_FLG_*) */
Elf32_Half vd_ndx; /* version index */
Elf32_Half vd_cnt; /* number of verdaux entries */
Elf32_Word vd_hash; /* hash of name */
Elf32_Word vd_aux; /* offset to verdaux entries */
Elf32_Word vd_next; /* offset to next verdef */
} Elf32_Verdef;
typedef struct {
Elf32_Word vda_name; /* string table offset of name */
Elf32_Word vda_next; /* offset to verdaux */
} Elf32_Verdaux;
typedef struct {
Elf32_Half vn_version; /* version number of structure */
Elf32_Half vn_cnt; /* number of vernaux entries */
Elf32_Word vn_file; /* string table offset of library name*/
Elf32_Word vn_aux; /* offset to vernaux entries */
Elf32_Word vn_next; /* offset to next verneed */
} Elf32_Verneed;
typedef struct {
Elf32_Word vna_hash; /* Hash of dependency name */
Elf32_Half vna_flags; /* flags (VER_FLG_*) */
Elf32_Half vna_other; /* unused */
Elf32_Word vna_name; /* string table offset to version name*/
Elf32_Word vna_next; /* offset to next vernaux */
} Elf32_Vernaux;
typedef struct {
Elf32_Half vs_vers;
} Elf32_Versym;
#ifndef _LKM
#include "opt_execfmt.h"
#endif
#ifdef EXEC_ELF32
int exec_elf32_makecmds(struct lwp *, struct exec_package *);
int elf32_copyargs(struct lwp *, struct exec_package *,
struct ps_strings *, char **, void *);
int coredump_elf32(struct lwp *, void *);
int coredump_writenote_elf32(struct proc *, void *, Elf32_Nhdr *,
const char *, void *);
int elf32_check_header(Elf32_Ehdr *, int);
#endif
#ifdef EXEC_ELF64
int exec_elf64_makecmds(struct lwp *, struct exec_package *);
int elf64_copyargs(struct lwp *, struct exec_package *,
struct ps_strings *, char **, void *);
int coredump_elf64(struct lwp *, void *);
int coredump_writenote_elf64(struct proc *, void *, Elf64_Nhdr *,
const char *, void *);
int elf64_check_header(Elf64_Ehdr *, int);
#endif
#endif /* _KERNEL */
#endif /* !_SYS_EXEC_ELF_H_ */