base: Genode's dynamic linker

Issue #1280
This commit is contained in:
Sebastian Sumpf 2014-05-20 11:40:50 +02:00 committed by Christian Helmuth
parent 8738673625
commit 5a821d4c92
123 changed files with 3203 additions and 13034 deletions

View File

@ -0,0 +1,97 @@
/**
* \brief Dynamic linker interface
* \author Sebastian Sumpf
* \date 2014-10-09
*/
#ifndef _INCLUDE__BASE__SHARED_OBJECT_H_
#define _INCLUDE__BASE__SHARED_OBJECT_H_
#include <base/exception.h>
#include <base/stdint.h>
namespace Genode {
class Shared_object;
struct Address_info;
};
class Genode::Shared_object
{
private:
void *_handle = nullptr;
void *_lookup(const char *symbol) const;
public:
class Invalid_file : public Genode::Exception { };
class Invalid_symbol : public Genode::Exception { };
enum open_flags {
NOW = 0x1,
LAZY = 0x2,
KEEP = 0x4, /* do not unload on destruction */
};
/**
* Load shared object and dependencies
*
* \param file Shared object to load
* \param flags LAZY for lazy function binding, NOW for immediate binding
*
* \throw Invalid_file
*/
Shared_object(char const *file = nullptr, unsigned flags = LAZY);
/**
* Close and unload shared object
*/
~Shared_object();
/**
* Lookup a symbol in shared object and it's dependencies
*
* \param symbol Symbol name
*
* \throw Invalid_symbol
*
* \return Symbol address
*/
template<typename T = void *> T lookup(const char *symbol) const
{
return static_cast<T>(_lookup(symbol));
}
/**
* Link information
*/
struct Link_map
{
Genode::addr_t addr; /* load address */
char const *path; /* object path */
void const *dynamic; /* pointer to DYNAMIC section */
Link_map *next;
Link_map *prev;
};
/**
* Return link map of shared object
*/
Link_map const * link_map() const;
};
struct Genode::Address_info
{
char const *path; /* path of shared object */
Genode::addr_t base; /* base of shared object */
char const *name; /* name of symbol */
Genode::addr_t addr; /* address of symbol */
class Invalid_address : public Genode::Exception { };
Address_info(Genode::addr_t addr);
};
#endif /* _INCLUDE__BASE__SHARED_OBJECT_H_ */

View File

@ -0,0 +1,6 @@
REQUIRES = arm
include $(REP_DIR)/lib/mk/ldso.inc
INC_DIR += $(DIR)/arm
vpath %.s $(DIR)/arm

View File

@ -0,0 +1,22 @@
SHARED_LIB = yes
DIR = $(REP_DIR)/src/lib/ldso
include $(BASE_DIR)/mk/base-libs.mk
LIBS = $(BASE_LIBS)
SRC_CC = main.cc test.cc file.cc
SRC_S = jmp_slot.s
INC_DIR += $(DIR)/include
LD_OPT += -Bsymbolic-functions --version-script=$(DIR)/symbol.map
ENTRY_POINT = _start
ifneq ($(filter linux, $(SPECS)),)
LD_OPT += -T$(call select_from_repositories,src/platform/context_area.nostdlib.ld)
else
LD_OPT += -T$(DIR)/linker.ld
endif
vpath %.cc $(DIR)
# vi:ft=make

View File

@ -0,0 +1,6 @@
REQUIRES = x86 32bit
include $(REP_DIR)/lib/mk/ldso.inc
INC_DIR += $(DIR)/x86_32
vpath %.s $(DIR)/x86_32

View File

@ -0,0 +1,6 @@
REQUIRES = x86 64bit
include $(REP_DIR)/lib/mk/ldso.inc
INC_DIR += $(DIR)/x86_64
vpath %.s $(DIR)/x86_64

View File

@ -139,7 +139,7 @@ $(LIB_A): $(OBJECTS)
# Don't link base libraries against shared libraries except for ld.lib.so
#
ifdef SHARED_LIB
ifneq ($(LIB),ld)
ifneq ($(LIB),$(DYNAMIC_LINKER))
override DEPS := $(filter-out $(BASE_LIBS:=.lib),$(DEPS))
endif
endif
@ -173,7 +173,7 @@ USED_SO_FILES := $(foreach s,$(USED_SHARED_LIBS),$(LIB_CACHE_DIR)/$s/$s.lib.s
#
# Don't link ld libary against shared objects
#
USED_SO_FILES := $(filter-out %ld.lib.so,$(USED_SO_FILES))
USED_SO_FILES := $(filter-out %$(DYNAMIC_LINKER).lib.so,$(USED_SO_FILES))
#
# Default entry point of shared libraries

View File

@ -1,4 +1,4 @@
This directory contains the port of the dynamic linker (ldso) from FreeBSD.
This directory contains Genode's dynamic linker (ldso)
Usage
@ -11,14 +11,32 @@ declare 'SHARED_LIB = yes' in the library-description file. When doing so, a
library, no special precautions are needed. The build system will automatically
detect the use of shared libraries, concludes that the binary must be
dynamically linked, and will use the correct linker script. When loading a
dynamically linked program, the dynamic linker 'lsdo' and all used shared
dynamically linked program, the dynamic linker 'ldso.lib.so' and all used shared
objects must be loaded as well.
The linker can be configured through the '<config>' node when loading a dynamic
binary. Currently there are to configurations options, 'ld_bind_now="yes"'
causes the linker to resolve all symbol references on program loading.
'ld_verbose="yes"' outputs library load informations before starting the
program.
Configuration snippet:
!<!-- bind immediately, no library informations -->
!<start name="dynamic_binary">
! <resource name="RAM" quantum="1M" />
! <config ld_bind_now="yes" ld_verbose="no">
! </config>
!</start>
Debugging dynamic binaries with GDB stubs
-----------------------------------------
! # go to directory containing the binaries
! cd <build/dir>/bin
!
! # start GDB with binary to debug
! gdb <path to binary>
! gdb <binary name>
!
! # break in main routine
! b main
@ -26,7 +44,7 @@ Debugging dynamic binaries with GDB stubs
! # inspect loaded shared libraries
! info sharedlibrary
!
! # load shared symbols of shared libaries
! # load shared symbols of shared libraries (if not already loaded)
! share
!
! # from here you can debug within libraries

View File

@ -0,0 +1,39 @@
/**
* \brief Jump slot entry code for ARM platforms
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
.text
.globl _jmp_slot
.type _jmp_slot,%function
/*
* stack[0] = RA
* ip = &GOT[n+3]
* lr = &GOT[2]
*/
_jmp_slot:
stmdb sp!,{r0-r4,sl,fp}
/* retrieve relocation index */
sub r1, ip, lr /* r1 = 4 * (n + 1) */
sub r1, r1, #4 /* r1 = 4 * n */
lsr r1, r1, #2 /* r1 = n */
ldr r0, [lr, #-4] /* obj pointer from PLOTGOT[1] */
mov r4, ip /* safe got location */
bl jmp_slot /* call linker(obj, index) */
str r0, [r4] /* save symbol value in GOT */
mov ip, r0
ldmia sp!,{r0-r4,sl,fp,lr} /* restore the stack */
mov pc, ip /* jump to symbol address */

View File

@ -0,0 +1,118 @@
/**
* \brief ARM specific relocations
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__ARM__RELOCATION_H_
#define _INCLUDE__ARM__RELOCATION_H_
#include <relocation_generic.h>
namespace Linker {
enum Reloc_types {
R_ABS32 = 2,
R_REL32 = 3,
R_COPY = 20,
R_GLOB_DAT = 21,
R_JMPSLOT = 22,
R_RELATIVE = 23,
};
class Reloc_non_plt;
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, false> Reloc_jmpslot;
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
};
class Linker::Reloc_non_plt : public Reloc_non_plt_generic
{
private:
void _rel32(Elf::Rel const *rel, Elf::Addr *addr)
{
Elf::Addr reloc_base;
Elf::Sym const *sym;
if (!(sym = locate_symbol(rel->sym(), _dag, &reloc_base)))
return;
/* S + A - P */
*addr = reloc_base + sym->st_value - (Elf::Addr)addr + *addr;
trace("REL32", (unsigned long)addr, *addr, 0);
}
void _glob_dat(Elf::Rel const *rel, Elf::Addr *addr, bool no_addend)
{
Elf::Addr reloc_base;
Elf::Sym const *sym;
if (!(sym = locate_symbol(rel->sym(), _dag, &reloc_base)))
return;
Elf::Addr addend = no_addend ? 0 : *addr;
/* S + A */
*addr = addend + reloc_base + sym->st_value;
trace("GLOB_DAT", (unsigned long)addr, *addr, 0);
}
void _relative(Elf::Addr *addr)
{
/*
* This ommits the linker and the binary, the linker has relative
* relocations within its text-segment (e.g., 'initial_sp' and friends), which
* we cannot write to from here).
*/
if (_dag->obj->reloc_base())
*addr += _dag->obj->reloc_base();
}
public:
Reloc_non_plt(Dag const *dag, Elf::Rela const *, unsigned long)
: Reloc_non_plt_generic(dag)
{
PERR("LD: DT_RELA not supported");
throw Incompatible();
}
Reloc_non_plt(Dag const *dag, Elf::Rel const *rel, unsigned long size, bool second_pass)
: Reloc_non_plt_generic(dag)
{
Elf::Rel const *end = rel + (size / sizeof(Elf::Rel));
for (; rel < end; rel++) {
Elf::Addr *addr = (Elf::Addr *)(_dag->obj->reloc_base() + rel->offset);
if (second_pass && rel->type() != R_GLOB_DAT)
continue;
switch (rel->type()) {
case R_REL32 : _rel32(rel, addr); break;
case R_COPY : _copy<Elf::Rel>(rel, addr); break;
case R_ABS32 :
case R_GLOB_DAT: _glob_dat(rel, addr, second_pass); break;
case R_RELATIVE: _relative(addr); break;
default:
trace("UNKREL", rel->type(), 0, 0);
if (_dag->root) {
PWRN("LD: Unkown relocation %u", rel->type());
throw Incompatible();
}
break;
}
}
}
};
#endif /* _INCLUDE__ARM__RELOCATION_H_ */

View File

@ -0,0 +1,307 @@
/**
* \brief ELF loading/unloading support
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <linker.h>
#include <base/allocator_avl.h>
#include <os/attached_rom_dataspace.h>
#include <rm_session/connection.h>
#include <util/construct_at.h>
char const *Linker::ELFMAG = "\177ELF";
using namespace Linker;
using namespace Genode;
namespace Linker
{
class Rm_area;
struct Elf_file;
}
/**
* Managed dataspace for ELF files (singelton)
*/
class Linker::Rm_area : public Rm_connection
{
private:
/* size of dataspace */
enum { RESERVATION = 160 * 1024 * 1024 };
addr_t _base; /* base address of dataspace */
Allocator_avl _range; /* VM range allocator */
protected:
Rm_area(addr_t base)
: Rm_connection(0, RESERVATION), _range(env()->heap())
{
on_destruction(KEEP_OPEN);
_base = (addr_t) env()->rm_session()->attach_at(dataspace(), base);
_range.add_range(base, RESERVATION);
}
public:
static Rm_area *r(addr_t base = 0)
{
/*
* The capabilities in this class become invalid when doing a
* fork in the noux environment. Hence avoid destruction of
* the singleton object as the destructor would try to access
* the capabilities also in the forked process.
*/
static bool constructed = 0;
static char placeholder[sizeof(Rm_area)];
if (!constructed) {
construct_at<Rm_area>(placeholder, base);
constructed = 1;
}
return reinterpret_cast<Rm_area *>(placeholder);
}
/**
* Reserve VM region of 'size' at 'vaddr'. Allocate any free region if
* 'vaddr' is zero
*/
addr_t alloc_region(size_t size, addr_t vaddr = 0)
{
addr_t addr = vaddr;
if (addr && (_range.alloc_addr(size, addr).is_error()))
throw Region_conflict();
else if (!addr && _range.alloc_aligned(size, (void **)&addr, 12).is_error())
throw Region_conflict();
return addr;
}
void free_region(addr_t vaddr) { _range.free((void *)vaddr); }
/**
* Overwritten from 'Rm_connection'
*/
Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_at(ds, local_addr - _base, size, offset); }
/**
* Overwritten from 'Rm_connection'
*/
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_executable(ds, local_addr - _base, size, offset); }
void detach(Local_addr local_addr) {
Rm_connection::detach((addr_t)local_addr - _base); }
};
/**
* Map ELF files
*/
struct Linker::Elf_file : File
{
Rom_connection rom;
Ram_dataspace_capability ram_cap[Phdr::MAX_PHDR];
bool loaded;
Elf_file(char const *name, bool load = true)
:
rom(name), loaded(load)
{
load_phdr();
if (load)
load_segments();
}
virtual ~Elf_file()
{
if (loaded)
unload_segments();
}
/**
* Check if ELF is sane
*/
bool check_compat(Elf::Ehdr const *ehdr)
{
if (memcmp(ehdr, ELFMAG, SELFMAG) != 0) {
PERR("LD: binary is not an ELF");
return false;
}
if (ehdr->e_ident[EI_CLASS] != ELFCLASS) {
PERR("LD: support for 32/64-bit objects only");
return false;;
}
return true;
}
/**
* Copy program headers and read entry point
*/
void load_phdr()
{
Elf::Ehdr *ehdr = (Elf::Ehdr *)env()->rm_session()->attach(rom.dataspace(), 0x1000);
if (!check_compat(ehdr))
throw Incompatible();
/* set entry point and program header information */
phdr.count = ehdr->e_phnum;
entry = (Entry)ehdr->e_entry;
/* copy program headers */
addr_t header = (addr_t)ehdr + ehdr->e_phoff;
for (unsigned i = 0; i < phdr.count; i++, header += ehdr->e_phentsize)
memcpy(&phdr.phdr[i], (void *)header, ehdr->e_phentsize);
env()->rm_session()->detach(ehdr);
Phdr p;
loadable_segments(p);
/* start vaddr */
start = trunc_page(p.phdr[0].p_vaddr);
Elf::Phdr *ph = &p.phdr[p.count - 1];
/* size of lodable segments */
size = round_page(ph->p_vaddr + ph->p_memsz) - start;
}
/**
* Find PT_LOAD segemnts
*/
void loadable_segments(Phdr &result)
{
for (unsigned i = 0; i < phdr.count; i++) {
Elf::Phdr *ph = &phdr.phdr[i];
if (ph->p_type != PT_LOAD)
continue;
if (ph->p_align & (0x1000 - 1)) {
PERR("LD: Unsupported alignment %p", (void *)ph->p_align);
throw Incompatible();
}
result.phdr[result.count++] = *ph;
}
}
bool is_rx(Elf::Phdr const &ph) {
return ((ph.p_flags & PF_MASK) == (PF_R | PF_X)); }
bool is_rw(Elf::Phdr const &ph) {
return ((ph.p_flags & PF_MASK) == (PF_R | PF_W)); }
/**
* Load PT_LOAD segments
*/
void load_segments()
{
Phdr p;
/* search for PT_LOAD */
loadable_segments(p);
/* allocate region */
reloc_base = Rm_area::r(start)->alloc_region(size, start);
reloc_base = (start == reloc_base) ? 0 : reloc_base;
if (verbose_loading)
PDBG("reloc_base: " EFMT " start: " EFMT " end: " EFMT,
reloc_base, start, reloc_base + start + size);
for (unsigned i = 0; i < p.count; i++) {
Elf::Phdr *ph = &p.phdr[i];
if (is_rx(*ph))
load_segment_rx(*ph);
else if (is_rw(*ph))
load_segment_rw(*ph, i);
else {
PERR("LD: Non-RW/RX segment");
throw Invalid_file();
}
}
}
/**
* Map read-only segment
*/
void load_segment_rx(Elf::Phdr const &p)
{
Rm_area::r()->attach_executable(rom.dataspace(),
trunc_page(p.p_vaddr) + reloc_base,
round_page(p.p_memsz),
trunc_page(p.p_offset));
}
/**
* Copy read-write segment
*/
void load_segment_rw(Elf::Phdr const &p, int nr)
{
void *src = env()->rm_session()->attach(rom.dataspace(), 0, p.p_offset);
addr_t dst = p.p_vaddr + reloc_base;
ram_cap[nr] = env()->ram_session()->alloc(p.p_memsz);
Rm_area::r()->attach_at(ram_cap[nr], dst);
memcpy((void*)dst, src, p.p_filesz);
/* clear if file size < memory size */
if (p.p_filesz < p.p_memsz)
memset((void *)(dst + p.p_filesz), 0, p.p_memsz - p.p_filesz);
env()->rm_session()->detach(src);
}
/**
* Unmap segements, RM regions, and free allocated dataspaces
*/
void unload_segments()
{
Phdr p;
loadable_segments(p);
/* detach from RM area */
for (unsigned i = 0; i < p.count; i++)
Rm_area::r()->detach(trunc_page(p.phdr[i].p_vaddr) + reloc_base);
/* free region from RM area */
Rm_area::r()->free_region(trunc_page(p.phdr[0].p_vaddr) + reloc_base);
/* free ram of RW segments */
for (unsigned i = 0; i < Phdr::MAX_PHDR; i++)
if (ram_cap[i].valid()) {
env()->ram_session()->free(ram_cap[i]);
}
}
};
File const *Linker::load(char const *path, bool load)
{
if (verbose_loading)
PDBG("loading: %s (PHDRS only: %s)", path, load ? "no" : "yes");
Elf_file *file = new(env()->heap()) Elf_file(Linker::file(path), load);
return file;
}

View File

@ -0,0 +1,458 @@
/**
* \brief ELF binary definitions
* \author Christian Helmuth
* \author Sebastian Sumpf
* \date 2014-05-16
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__ELF_H_
#define _INCLUDE__ELF_H_
#include <base/stdint.h>
namespace Linker {
/* standard ELF types. */
/* type for a 16-bit quantity. */
typedef genode_uint16_t Elf32_Half;
typedef genode_uint16_t Elf64_Half;
/* types for signed and unsigned 32-bit quantities */
typedef genode_uint32_t Elf32_Word;
typedef genode_int32_t Elf32_Sword;
typedef genode_uint32_t Elf64_Word;
typedef genode_int32_t Elf64_Sword;
/* types for signed and unsigned 64-bit quantities */
typedef genode_uint64_t Elf32_Xword;
typedef genode_int64_t Elf32_Sxword;
typedef genode_uint64_t Elf64_Xword;
typedef genode_int64_t Elf64_Sxword;
/* type of addresses */
typedef genode_uint32_t Elf32_Addr;
typedef genode_uint64_t Elf64_Addr;
/* type of file offsets */
typedef genode_uint32_t Elf32_Off;
typedef genode_uint64_t Elf64_Off;
/* type for section indices, which are 16-bit quantities */
typedef genode_uint16_t Elf32_Section;
typedef genode_uint16_t Elf64_Section;
/* type for version symbol information */
typedef Elf32_Half Elf32_Versym;
typedef Elf64_Half Elf64_Versym;
/**
* Fields in the e_ident array of ELF file header The EI_* macros are indices
* into the array. The macros under each EI_* macro are the values the byte
* may have.
*/
enum {
EI_NIDENT = 16, /* size of e_ident array in ELF header */
EI_MAG0 = 0, /* file identification byte 0 index */
ELFMAG0 = 0x7f, /* magic number byte 0 */
EI_MAG1 = 1, /* file identification byte 1 index */
ELFMAG1 = 'E', /* magic number byte 1 */
EI_MAG2 = 2, /* file identification byte 2 index */
ELFMAG2 = 'L', /* magic number byte 2 */
EI_MAG3 = 3, /* file identification byte 3 index */
ELFMAG3 = 'F', /* magic number byte 3 */
};
/**
* Conglomeration of the identification bytes, for easy testing as a word
*/
extern const char *ELFMAG;
enum {
SELFMAG = 4,
EI_CLASS = 4, /* file class byte index */
ELFCLASSNONE = 0, /* invalid class */
ELFCLASS32 = 1, /* 32-bit objects */
ELFCLASS64 = 2, /* 64-bit objects */
ELFCLASSNUM = 3,
EI_DATA = 5, /* data encoding byte index */
ELFDATANONE = 0, /* invalid data encoding */
ELFDATA2LSB = 1, /* 2's complement, little endian */
ELFDATA2MSB = 2, /* 2's complement, big endian */
ELFDATANUM = 3,
EI_ABIVERSION = 8, /* ABI version */
EI_PAD = 9, /* byte index of padding bytes */
};
/**
* Legal values for e_type (object file type)
*/
enum {
ET_NONE = 0, /* no file type */
ET_EXEC = 2, /* executable file */
ET_DYN = 3, /* shared object file */
};
/**
* Legal values for e_machine (architecture)
*/
enum {
EM_NONE = 0, /* no machine */
EM_386 = 3, /* intel 80386 */
};
/**
* Legal values for e_version (version)
*/
enum {
EV_NONE = 0, /* invalid ELF version */
EV_CURRENT = 1, /* current version */
EV_NUM = 2,
};
/**
* Legal values for p_type (segment type)
*/
enum {
PT_NULL = 0, /* program header table entry unused */
PT_LOAD = 1, /* loadable program segment */
PT_DYNAMIC = 2, /* dynamic linking information */
PT_INTERP = 3, /* program interpreter */
PT_NOTE = 4, /* auxiliary information */
PT_SHLIB = 5, /* reserved */
PT_PHDR = 6, /* entry for header table itself */
PT_TLS = 7, /* thread-local storage segment */
PT_NUM = 8, /* number of defined types */
PT_LOOS = 0x60000000, /* start of OS-specific */
PT_GNU_EH_FRAME = 0x6474e550, /* gcc .eh_frame_hdr segment */
PT_GNU_STACK = 0x6474e551, /* indicates stack executability */
PT_GNU_RELRO = 0x6474e552, /* read-only after relocation */
PT_LOPROC = 0x70000000, /* first processor-specific type */
PT_ARM_EXIDX = 0x70000001, /* location of exception tables */
PT_HIPROC = 0x7fffffff, /* last processor-specific type */
};
/**
* Legal values for p_flags (segment flags)
*/
enum {
PF_X = (1 << 0), /* segment is executable */
PF_W = (1 << 1), /* segment is writable */
PF_R = (1 << 2), /* segment is readable */
PF_MASK = 0x7,
};
/**
* Tag value for Elf::Dyn
*/
enum D_tag
{
DT_NULL = 0,
DT_NEEDED = 1, /* dependend libraries */
DT_PLTRELSZ = 2, /* size of PLT relocations */
DT_PLTGOT = 3, /* processor dependent address */
DT_HASH = 4, /* address of symbol hash table */
DT_STRTAB = 5, /* string table */
DT_SYMTAB = 6, /* address of symbol table */
DT_RELA = 7, /* ELF relocation with addend */
DT_RELASZ = 8, /* total size of RELA reolcations */
DT_STRSZ = 10, /* size of string table */
DT_INIT = 12, /* ctors */
DT_REL = 17, /* address of Elf::Rel relocations */
DT_RELSZ = 18, /* sizof Elf::Rel relocation */
DT_PLTREL = 20, /* PLT relcation */
DT_DEBUG = 21, /* debug structure location */
DT_JMPREL = 23, /* address of PLT relocation */
};
/**
* Symbol table
*/
enum Symbol_table {
/* Termination symbol for hash chains */
STN_UNDEF = 0,
/* Bindings */
STB_LOCAL = 0, /* local symbol */
STB_WEAK = 2, /* weak symbol */
/* Types */
STT_NOTYPE = 0, /* type unspecified */
STT_OBJECT = 1, /* data */
STT_FUNC = 2, /* function */
/* Section table index */
SHN_UNDEF = 0, /* undefined */
SHN_COMMON = 0xfff2, /* common data */
};
/********************************
** 32-Bit non-POD definitions **
********************************/
namespace Elf32 {
typedef Elf32_Addr Addr;
typedef Elf32_Word Hashelt;
typedef Elf32_Word Size;
typedef Elf32_Half Half;
/**
* The ELF file header
*/
struct Ehdr
{
unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
Elf32_Half e_type; /* Object file type */
Elf32_Half e_machine; /* Architecture */
Elf32_Word e_version; /* Object file version */
Elf32_Addr e_entry; /* Entry point virtual address */
Elf32_Off e_phoff; /* Program header table file offset */
Elf32_Off e_shoff; /* Section header table file offset */
Elf32_Word e_flags; /* Processor-specific flags */
Elf32_Half e_ehsize; /* ELF header size in bytes */
Elf32_Half e_phentsize; /* Program header table entry size */
Elf32_Half e_phnum; /* Program header table entry count */
Elf32_Half e_shentsize; /* Section header table entry size */
Elf32_Half e_shnum; /* Section header table entry count */
Elf32_Half e_shstrndx; /* Section header string table index */
};
/**
* Program segment header
*/
struct Phdr
{
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment file offset */
Elf32_Addr p_vaddr; /* segment virtual address */
Elf32_Addr p_paddr; /* segment physical address */
Elf32_Word p_filesz; /* segment size in file */
Elf32_Word p_memsz; /* segment size in memory */
Elf32_Word p_flags; /* segment flags */
Elf32_Word p_align; /* segment alignment */
};
/**
* Dynamic structure (section .dynamic)
*/
struct Dyn
{
Elf32_Sword tag; /* entry type */
union {
Elf32_Word val; /* integer value */
Elf32_Addr ptr; /* address value */
} un;
};
/**
* Relocation
*/
struct Rel
{
Elf32_Addr offset; /* location to be relocated */
Elf32_Word info; /* relocation type and symbol index */
/**
* Relocation type
*/
int type() const { return info & 0xff; }
/**
* Symbol table index
*/
unsigned sym() const { return info >> 8; }
};
/**
* Relocations that need an addend field
*/
struct Rela
{
Elf32_Addr r_offset; /* location to be relocated */
Elf32_Word r_info; /* relocation type and symbol index */
Elf32_Sword r_addend; /* addend */
};
/**
* Symbol table entry
*/
struct Sym
{
Elf32_Word st_name; /* string table index of name */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* size of associated object */
unsigned char st_info; /* type and binding information */
unsigned char st_other; /* reserved (not used) */
Elf32_Half st_shndx; /* section index of symbol */
/**
* Binding information
*/
unsigned char bind() const { return st_info >> 4; }
/**
* Type information
*/
unsigned char type() const { return st_info & 0xf; }
/**
* Check for weak symbol
*/
bool weak() const { return bind() == STB_WEAK; }
};
}
/********************************
** 64-Bit non-POD definitions **
********************************/
namespace Elf64 {
typedef Elf64_Addr Addr;
typedef Elf64_Word Hashelt;
typedef Elf64_Xword Size;
typedef Elf64_Half Half;
/**
* ELF header
*/
struct Ehdr
{
unsigned char e_ident[EI_NIDENT]; /* magic number and other info */
Elf64_Half e_type; /* object file type */
Elf64_Half e_machine; /* architecture */
Elf64_Word e_version; /* object file version */
Elf64_Addr e_entry; /* entry point virtual address */
Elf64_Off e_phoff; /* program header table file offset */
Elf64_Off e_shoff; /* section header table file offset */
Elf64_Word e_flags; /* processor-specific flags */
Elf64_Half e_ehsize; /* eLF header size in bytes */
Elf64_Half e_phentsize; /* program header table entry size */
Elf64_Half e_phnum; /* program header table entry count */
Elf64_Half e_shentsize; /* section header table entry size */
Elf64_Half e_shnum; /* section header table entry count */
Elf64_Half e_shstrndx; /* section header string table index */
};
/**
* Program header
*/
struct Phdr
{
Elf64_Word p_type; /* segment type */
Elf64_Word p_flags; /* segment flags */
Elf64_Off p_offset; /* segment file offset */
Elf64_Addr p_vaddr; /* segment virtual address */
Elf64_Addr p_paddr; /* segment physical address */
Elf64_Xword p_filesz; /* segment size in file */
Elf64_Xword p_memsz; /* segment size in memory */
Elf64_Xword p_align; /* segment alignment */
};
/**
* Dynamic structure (section .dynamic)
*/
struct Dyn
{
Elf64_Sxword tag; /* entry type. */
union
{
Elf64_Xword val; /* integer value. */
Elf64_Addr ptr; /* address value. */
} un;
};
/**
* Relocation
*/
struct Rel
{
Elf64_Addr r_offset; /* location to be relocated. */
Elf64_Xword r_info; /* relocation type and symbol index. */
};
/**
* Relocations that need an addend field
*/
struct Rela
{
Elf64_Addr offset; /* location to be relocated */
Elf64_Xword info; /* relocation type and symbol index */
Elf64_Sxword addend; /* addend */
/**
* Relocation type
*/
int type() const { return info & 0xffffffffL; }
/**
* Symbol table index
*/
unsigned sym() const { return (info >> 16) >> 16; }
};
/**
* Symbol table entry
*/
struct Sym
{
Elf64_Word st_name; /* string table index of name */
unsigned char st_info; /* type and binding information */
unsigned char st_other; /* reserved (not used) */
Elf64_Half st_shndx; /* section index of symbol */
Elf64_Addr st_value; /* symbol value */
Elf64_Xword st_size; /* size of associated object */
/**
* Binding information
*/
unsigned char bind() const { return st_info >> 4; }
/**
* Type information
*/
unsigned char type() const { return st_info & 0xf; }
/**
* Check for weak symbol
*/
bool weak() const { return bind() == STB_WEAK; }
};
} /* namespace Elf64 */
} /* namespace Linker" */
/**
* Define bit-width independent types
*/
#ifdef __x86_64__
namespace Elf = Linker::Elf64;
#define ELFCLASS ELFCLASS64
#define EFMT "%llx"
#else
namespace Elf = Linker::Elf32;
#define ELFCLASS ELFCLASS32
#define EFMT "%x"
#endif /* _LP64 */
#endif /* _INCLUDE__ELF_H_ */

View File

@ -0,0 +1,230 @@
/**
* \brief Generic linker definitions
* \author Sebastian Sumpf
* \date 2014-10-24
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__LINKER_H_
#define _INCLUDE__LINKER_H_
#include <base/exception.h>
#include <base/env.h>
#include <util/fifo.h>
#include <util/misc_math.h>
#include <util/string.h>
#include <elf.h>
#include <trace.h>
/**
* Debugging
*/
constexpr bool verbose_lookup = false;
constexpr bool verbose_link_map = false;
constexpr bool verbose_relocation = false;
constexpr bool verbose_exception = false;
constexpr bool verbose_shared = false;
constexpr bool verbose_loading = false;
/**
* Forward declartions and helpers
*/
namespace Linker
{
class Object;
struct Phdr;
struct File;
struct Root_object;
struct Dag;
struct Elf_object;
/**
* Find symbol via index
*
* \param sym_index Symbol index within object
* \param dag Directed acyclic graph of object
* \param base Returned address of symbol
* \param undef True, return undefined symbol; False return defined
* symbols only
* \param other True, search for symbol in other objects; False, search
* for symbol in given object as well.
*
* \throw Not_found Symbol not found
*
* \return Symbol information
*/
Elf::Sym const *locate_symbol(unsigned sym_index, Dag const *, Elf::Addr *base,
bool undef = false, bool other = false);
/**
* Find symbol via name
*
* \param name Symbol name
* \param dag Directed acyclic graph of object
* \param base Returned address of symbol
* \param undef True, return undefined symbol; False return defined
* symbols only
* \param other True, search for symbol in other objects; False, search
* for symbol in given object as well.
*
* \throw Not_found Symbol not found
*
* \return Symbol information
*/
Elf::Sym const *search_symbol(char const *name, Dag const *dag, Elf::Addr *base,
bool undef = false, bool other = false);
/**
* Load object
*
* \param path Path of object
* \param load True, load binary; False, load ELF header only
*
* \throw Invalid_file Segment is neither read-only/executable or read/write
* \throw Region_conflict There is already something at the given address
* \throw Incompatible Not an ELF
*
* \return File descriptor
*/
File const *load(char const *path, bool load = true);
/**
* Exceptions
*/
class Incompatible : Genode::Exception { };
class Invalid_file : Genode::Exception { };
class Not_found : Genode::Exception { };
/**
* Page handling
*/
template <typename T>
static inline T trunc_page(T addr) {
return addr & Genode::_align_mask((T)12); }
template <typename T>
static inline T round_page(T addr) {
return Genode::align_addr(addr, (T)12); }
/**
* Extract file name from path
*/
inline char const *file(char const *path)
{
/* strip directories */
char const *f, *r = path;
for (f = r; *f; f++)
if (*f == '/')
r = f + 1;
return r;
}
/**
* Invariants
*/
constexpr char const *binary_name() { return "binary"; }
constexpr char const *linker_name() { return "ld.lib.so"; }
}
struct Linker::Phdr
{
enum { MAX_PHDR = 10 };
Elf::Phdr phdr[MAX_PHDR];
unsigned count = 0;
};
struct Linker::File
{
typedef void (*Entry)(void);
Phdr phdr;
Entry entry;
Elf::Addr reloc_base = 0;
Elf::Addr start = 0;
Elf::Size size = 0;
virtual ~File() { }
Elf::Phdr const *elf_phdr(unsigned index) const
{
if (index < phdr.count)
return &phdr.phdr[index];
return 0;
}
unsigned elf_phdr_count() const { return phdr.count; }
};
class Linker::Object : public Genode::Fifo<Object>::Element
{
protected:
enum { MAX_PATH = 128 };
char _name[MAX_PATH];
File const *_file = nullptr;
public:
Object() { }
Object(char const *path, File const *file)
: _file(file)
{
Genode::strncpy(_name, Linker::file(path), MAX_PATH);
}
virtual ~Object()
{
if (_file)
destroy(Genode::env()->heap(), const_cast<File *>(_file));
}
Elf::Addr reloc_base() const { return _file ? _file->reloc_base : 0; }
char const *name() const { return _name; }
File const *file() { return _file; }
virtual bool is_linker() const = 0;
virtual bool is_binary() const = 0;
Elf::Size const size() const { return _file ? _file->size : 0; }
};
struct Linker::Dag : Genode::Fifo<Dag>::Element
{
Object *obj = nullptr;
Root_object *root = nullptr;
Dag(Object *obj, Root_object *root) : obj(obj), root(root) { }
Dag(char const *path, Root_object *root, Genode::Fifo<Dag> * const dag,
unsigned flags = 0);
~Dag();
void load_needed(Genode::Fifo<Dag> * const dag, unsigned flags = 0);
bool in_dag(char const *file, Genode::Fifo<Dag> *const dag);
};
static inline bool verbose_reloc(Linker::Dag const *d)
{
return d->root && verbose_relocation;
}
extern "C" void _jmp_slot(void);
#endif /* _INCLUDE__LINKER_H_ */

View File

@ -0,0 +1,176 @@
/**
* \brief Generic relocation classes
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__RELOCATION_GENERIC_H_
#define _INCLUDE__RELOCATION_GENERIC_H_
#include <linker.h>
namespace Linker
{
struct Plt_got;
template <typename REL, unsigned TYPE, bool DIV> class Reloc_jmpslot_generic;
template <typename REL, unsigned TYPE, unsigned JMPSLOT> struct Reloc_plt_generic;
template <typename REL, unsigned TYPE> struct Reloc_bind_now_generic;
class Reloc_non_plt_generic;
}
/**
* Set 2nd and 3rd GOT entry (see: SYSTEM V APPLICATION BINARY INTERFACE
* Intel386 Architecture Processor Supplement - 5.9
*/
struct Linker::Plt_got
{
Plt_got(Dag const *dag, Elf::Addr *pltgot)
{
if (verbose_relocation)
PDBG("OBJ: %s (%p)", dag->obj->name(), dag);
pltgot[1] = (Elf::Addr) dag; /* ELF object */
pltgot[2] = (Elf::Addr) &_jmp_slot; /* Linker entry */
}
};
/**
* PLT relocations
*/
template<typename REL, unsigned TYPE, unsigned JMPSLOT>
struct Linker::Reloc_plt_generic
{
Reloc_plt_generic(Object const *obj, D_tag const type,
Elf::Rel const *start, unsigned long size)
{
if (type != TYPE) {
PERR("LD: Unsupported PLT relocation type: %u", type);
throw Incompatible();
}
REL const *rel = (REL const *)start;
REL const *end = rel + (size / sizeof(REL));
for (; rel < end; rel++) {
if (rel->type() != JMPSLOT) {
PERR("LD: Unsupported PLT relocation %u", rel->type());
throw Incompatible();
}
/* find relocation address and add relocation base */
Elf::Addr *addr = (Elf::Addr *)(obj->reloc_base() + rel->offset);
*addr += obj->reloc_base();
}
}
};
class Linker::Reloc_non_plt_generic
{
protected:
Dag const *_dag;
/**
* Copy relocations, these are just for the main program, we can do them
* safely here since all other DSO are loaded, relocated, and constructed at
* this point
*/
template <typename REL>
void _copy(REL const *rel, Elf::Addr *addr)
{
if (!_dag->obj->is_binary()) {
PERR("LD: Copy relocation in DSO (%s at %p)", _dag->obj->name(), addr);
throw Incompatible();
}
Elf::Sym const *sym;
Elf::Addr reloc_base;
/* search symbol in other objects, do not return undefined symbols */
if (!(sym = locate_symbol(rel->sym(), _dag, &reloc_base, false, true))) {
PWRN("LD: Symbol not found");
return;
}
Elf::Addr src = reloc_base + sym->st_value;
Genode::memcpy(addr, (void *)src, sym->st_size);
if (verbose_relocation)
PDBG("Copy relocation: " EFMT " -> %p (0x" EFMT " bytes) val: " EFMT "\n",
src, addr, sym->st_size, sym->st_value);
}
public:
Reloc_non_plt_generic(Dag const *dag) : _dag(dag) { }
};
/**
* Generic jmp slot handling
*/
template <typename REL, unsigned TYPE, bool DIV>
class Linker::Reloc_jmpslot_generic
{
Elf::Addr *_addr = 0;
public:
Reloc_jmpslot_generic(Dag const *dag, unsigned const type, Elf::Rel const* pltrel,
Elf::Size const index)
{
if (type != TYPE) {
PERR("LD: Unsupported JMP relocation type: %u", type);
throw Incompatible();
}
REL const *rel = &((REL *)pltrel)[index / (DIV ? sizeof(REL) : 1)];
Elf::Sym const *sym;
Elf::Addr reloc_base;
if (!(sym = locate_symbol(rel->sym(), dag, &reloc_base))) {
PWRN("LD: Symbol not found");
return;
}
/* write address of symbol to jump slot */
_addr = (Elf::Addr *)(dag->obj->reloc_base() + rel->offset);
*_addr = reloc_base + sym->st_value;
if (verbose_relocation) {
PDBG("jmp: rbase " EFMT " s: %p sval: " EFMT, reloc_base, sym, sym->st_value);
PDBG("jmp_slot at %p -> " EFMT, _addr, *_addr);
}
}
Elf::Addr target_addr() const { return *_addr; }
};
/**
* Relocate jump slots immediately
*/
template <typename REL, unsigned TYPE>
struct Linker::Reloc_bind_now_generic
{
Reloc_bind_now_generic(Dag const *dag, Elf::Rel const *pltrel, unsigned long const size)
{
Elf::Size last_index = size / sizeof(REL);
for (Elf::Size index = 0; index < last_index; index++)
Reloc_jmpslot_generic<REL, TYPE, false> reloc(dag, TYPE, pltrel, index);
}
};
#endif /* _INCLUDE__RELOCATION_GENERIC_H_ */

View File

@ -0,0 +1,38 @@
/**
* \brief Trace support for linker intialization
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__TRACE_H_
#define _INCLUDE__TRACE_H_
#if 0
typedef Genode::addr_t l4_umword_t;
typedef Genode::addr_t l4_addr_t;
namespace Fiasco {
#include <l4/sys/ktrace.h>
}
#else
namespace Fiasco {
inline void fiasco_tbuf_log_3val(char const *,unsigned, unsigned, unsigned) { }
}
extern "C" void wait_for_continue();
#endif
namespace Linker {
inline void trace(char const *str, unsigned v1, unsigned v2, unsigned v3)
{
Fiasco::fiasco_tbuf_log_3val(str, v1, v2, v3);
}
}
#endif /* _INCLUDE__TRACE_H_ */

View File

@ -13,6 +13,6 @@
SECTIONS
{
/* set ldso memory location */
. = 0x30000 - SIZEOF_HEADERS;
. = 0x30000;
}

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* \brief Our implementation of __gnu_Unwind_Find_exidx
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-07-05
*
*
* This file is used for ARM-EABI dynamic linking, only. The ARM cross-compiler
* uses this hook to locate a 'ARM.exidx' section within a shared object. For
* this to work 'dl_unwind_find_exidx' is excuted by 'ldso', which returns the

View File

@ -23,19 +23,6 @@
};
__dynamic_cast;
/*
* Standard dl interface
*/
dlclose;
dlerror;
dlopen;
dlsym;
dlvsym;
dladdr;
dllockinit;
dlinfo;
dl_iterate_phdr;
/*
* Debugging
*/
@ -49,10 +36,6 @@
__ldso_raise_exception*;
};
/*
* Exceptions symbols
*/
/* GNU verbose terminate handler */
extern "C++" { __gnu_cxx::__verbose_terminate_handler*; };
@ -67,6 +50,7 @@
_Unwind_DeleteException;
_Unwind_Resume;
__gxx_personality_v0;
dl_iterate_phdr;
/* ARM */
__aeabi_*;

View File

@ -0,0 +1,35 @@
/**
* \brief Jump slot entry code for x86_32
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
.text
.align 4
.globl _jmp_slot
.type _jmp_slot,@function
_jmp_slot:
pushf
pushl %eax
pushl %edx
pushl %ecx
pushl 0x14(%esp) /* relocation index */
pushl 0x14(%esp) /* obj pointer */
call jmp_slot@PLT
addl $8, %esp /* remove arguments from call */
movl %eax, 0x14(%esp) /* store synmbol value in obj pointer position */
popl %ecx
popl %edx
popl %eax
popf
leal 0x4(%esp), %esp /* remove relocation index */
ret /* return to symbol value */

View File

@ -0,0 +1,98 @@
/**
* \brief x86_32 specific relocations
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _X86_32__RELOCATION_H_
#define _X86_32__RELOCATION_H_
#include <relocation_generic.h>
namespace Linker {
enum Reloc_types {
R_32 = 1,
R_COPY = 5,
R_GLOB_DAT = 6,
R_JMPSLOT = 7,
R_RELATIVE = 8,
};
class Reloc_non_plt;
typedef Reloc_plt_generic<Elf::Rel, DT_REL, R_JMPSLOT> Reloc_plt;
typedef Reloc_jmpslot_generic<Elf::Rel, DT_REL, true> Reloc_jmpslot;
typedef Reloc_bind_now_generic<Elf::Rel, DT_REL> Reloc_bind_now;
}
class Linker::Reloc_non_plt : public Reloc_non_plt_generic
{
private:
void _glob_dat(Elf::Rel const *rel, Elf::Addr *addr, bool addend = false)
{
Elf::Addr reloc_base;
Elf::Sym const *sym;
if (!(sym = locate_symbol(rel->sym(), _dag, &reloc_base)))
return;
*addr = (addend ? *addr : 0) + reloc_base + sym->st_value;
trace("REL32", (unsigned long)addr, *addr, 0);
}
void _relative(Elf::Rel const *rel, Elf::Addr *addr)
{
if (_dag->obj->reloc_base())
*addr += _dag->obj->reloc_base();
}
public:
Reloc_non_plt(Dag const *dag, Elf::Rela const *, unsigned long)
: Reloc_non_plt_generic(dag)
{
PERR("LD: DT_RELA not supported");
trace("Non_plt", 0, 0, 0);
throw Incompatible();
}
Reloc_non_plt(Dag const *dag, Elf::Rel const *rel, unsigned long size, bool second_pass)
: Reloc_non_plt_generic(dag)
{
Elf::Rel const *end = rel + (size / sizeof(Elf::Rel));
for (; rel < end; rel++) {
Elf::Addr *addr = (Elf::Addr *)(_dag->obj->reloc_base() + rel->offset);
if (second_pass && rel->type() != R_GLOB_DAT)
continue;
switch (rel->type()) {
case R_32 : _glob_dat(rel, addr, true); break;
case R_GLOB_DAT: _glob_dat(rel, addr); break;
case R_COPY : _copy<Elf::Rel>(rel, addr); break;
case R_RELATIVE: _relative(rel, addr); break;
default:
trace("UNKREL", rel->type(), 0, 0);
if (_dag->root) {
PWRN("LD: Unkown relocation %u", rel->type());
throw Incompatible();
}
break;
}
}
}
};
#endif /* _X86_32__RELOCATION_H_ */

View File

@ -0,0 +1,52 @@
/**
* \brief Jump slot entry code for x86_64
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
.text
.align 4
.globl _jmp_slot
.type _jmp_slot,@function
_jmp_slot:
subq $8, %rsp
pushfq
pushq %rax
pushq %rdx
pushq %rcx
pushq %rsi
pushq %rdi
pushq %r8
pushq %r9
pushq %r10
pushq %r11
/* obj pointer */
movq 0x58(%rsp), %rdi
/* relocation index */
movq 0x60(%rsp), %rsi
call jmp_slot@PLT
/* rax now contains target symbol address */
movq %rax, 0x60(%rsp)
popq %r11
popq %r10
popq %r9
popq %r8
popq %rdi
popq %rsi
popq %rcx
popq %rdx
popq %rax
popfq
leaq 16(%rsp), %rsp
ret

View File

@ -0,0 +1,104 @@
/**
* \brief x86_64 specific relocations
* \author Sebastian Sumpf
* \date 2014-10-26
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _INCLUDE__X86_64__RELOCATION_H_
#define _INCLUDE__X86_64__RELOCATION_H_
#include <relocation_generic.h>
namespace Linker {
/**
* Relocation types
*/
enum Reloc_types {
R_64 = 1, /* add 64 bit symbol value. */
R_COPY = 5,
R_GLOB_DAT = 6, /* GOT entry to data address */
R_JMPSLOT = 7, /* jump slot */
R_RELATIVE = 8, /* add load addr of shared object */
};
class Reloc_non_plt;
typedef Reloc_plt_generic<Elf::Rela, DT_RELA, R_JMPSLOT> Reloc_plt;
typedef Reloc_jmpslot_generic<Elf::Rela, DT_RELA, false> Reloc_jmpslot;
typedef Reloc_bind_now_generic<Elf::Rela, DT_RELA> Reloc_bind_now;
};
class Linker::Reloc_non_plt : public Reloc_non_plt_generic
{
private:
/**
* Relative relocation (reloc base + addend)
*/
void _relative(Elf::Rela const *rel, Elf::Addr *addr)
{
trace("64", _dag->obj->reloc_base(), rel->addend, 0);
*addr = _dag->obj->reloc_base() + rel->addend;
}
/**
* GOT entry to data address or 64 bit symbol (addend = true),
* (reloc base of containing ojbect + symbol value (+ addend)
*/
void _glob_dat_64(Elf::Rela const *rel, Elf::Addr *addr, bool addend)
{
Elf::Addr reloc_base;
Elf::Sym const *sym;
if (!(sym = locate_symbol(rel->sym(), _dag, &reloc_base)))
return;
*addr = reloc_base + sym->st_value + (addend ? rel->addend : 0);
if (verbose_reloc(_dag))
PDBG("GLOB DAT %p -> %llx r %llx v %llx", addr, *addr, reloc_base,
sym->st_value);
}
public:
Reloc_non_plt(Dag const *dag, Elf::Rela const *rel, unsigned long size)
: Reloc_non_plt_generic(dag)
{
Elf::Rela const *end = rel + (size / sizeof(Elf::Rela));
for (; rel < end; rel++) {
Elf::Addr *addr = (Elf::Addr *)(_dag->obj->reloc_base() + rel->offset);
switch(rel->type()) {
case R_64: _glob_dat_64(rel, addr, true); break;
case R_GLOB_DAT: _glob_dat_64(rel, addr, false); break;
case R_COPY: _copy<Elf::Rela>(rel, addr); break;
case R_RELATIVE: _relative(rel, addr); break;
default:
trace("UNKRELA", rel->type(), 0, 0);
if (!_dag->obj->is_linker()) {
PWRN("LD: Unkown relocation %u", rel->type());
throw Incompatible();
}
break;
}
}
}
Reloc_non_plt(Dag const *dag, Elf::Rel const *, unsigned long, bool)
: Reloc_non_plt_generic(dag)
{
PERR("LD: DT_REL not supported");
throw Incompatible();
}
};
#endif /* _INCLUDE__X86_64__RELOCATION_H_ */

View File

@ -24,7 +24,6 @@ PHDRS
SECTIONS
{
/* Read-only sections, merged into text segment: */
. += SIZEOF_HEADERS;
.note.gnu.build-id : { *(.note.gnu.build-id) } : ro
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }

View File

@ -14,7 +14,7 @@ SRC_CC = atexit.cc dummies.cc rlimit.cc sysctl.cc \
gettimeofday.cc malloc.cc progname.cc fd_alloc.cc file_operations.cc \
plugin.cc plugin_registry.cc select.cc exit.cc environ.cc nanosleep.cc \
libc_mem_alloc.cc pread_pwrite.cc readv_writev.cc poll.cc \
libc_pdbg.cc vfs_plugin.cc rtc.cc
libc_pdbg.cc vfs_plugin.cc rtc.cc dynamic_linker.cc
INC_DIR += $(REP_DIR)/src/lib/libc

View File

@ -0,0 +1,5 @@
SRC_CC = lib_dl.cc
SHARED_LIB = yes
LIBS = test-ldso_lib_1
INC_DIR += $(REP_DIR)/src/test/ldso/include
vpath % $(REP_DIR)/src/test/ldso

View File

@ -2,7 +2,7 @@
if {[have_spec always_hybrid]} {
puts "Run script does not support hybrid Linux/Genode."; exit 0 }
build "core init test/ldso"
build "core init test/ldso test/ldso/dl"
create_boot_directory
@ -18,7 +18,7 @@ install_config {
</default-route>
<start name="test-ldso">
<resource name="RAM" quantum="2M"/>
<config>
<config ld_bind_now="no" ld_verbose="no">
<libc stdout="/dev/log">
<vfs> <dir name="dev"> <log/> </dir> </vfs>
</libc>
@ -27,7 +27,13 @@ install_config {
</config>
}
build_boot_image "core init test-ldso test-ldso_lib_1.lib.so test-ldso_lib_2.lib.so libc.lib.so libm.lib.so ld.lib.so"
set boot_modules {
core init test-ldso test-ldso_lib_1.lib.so
test-ldso_lib_2.lib.so test-ldso_lib_dl.lib.so
ld.lib.so libc.lib.so libm.lib.so
}
build_boot_image $boot_modules
append qemu_args "-nographic -m 64"
@ -103,13 +109,19 @@ compare_output_to {
[init -> test-ldso] exception in lib: caught
[init -> test-ldso] exception in another shared lib: caught
[init -> test-ldso]
[init -> test-ldso] test stack alignment
[init -> test-ldso] Test stack alignment
[init -> test-ldso] --------------------
[init -> test-ldso] <warning: unsupported format string argument>
[init -> test-ldso] <warning: unsupported format string argument>
[init -> test-ldso] <warning: unsupported format string argument>
[init -> test-ldso] <warning: unsupported format string argument>
[init -> test-ldso]
[init -> test-ldso] Dynamic cast
[init -> test-ldso] ------------
[init -> test-ldso] 'Object' called: good
[init -> test-ldso]
[init -> test-ldso] Destruction
[init -> test-ldso] -----------
[init -> test-ldso] ~Lib_2_local 55667785
[init -> test-ldso] ~Lib_1_local_2 1020303d
[init -> test-ldso] ~Lib_1_local_1 5060707d
@ -124,4 +136,3 @@ compare_output_to {
[init -> test-ldso] ~Lib_1_global_1 5060705
[init -> test-ldso] ~Lib_2_global 11223340
}

View File

@ -0,0 +1,120 @@
/**
* \brief DL interface bindings
* \author Sebastian Sumpf
* \date 2014-10-24
*
* Wrap Genode's shared library interface onto libc semantics.
*/
#include <base/env.h>
#include <base/printf.h>
#include <base/shared_object.h>
#include <base/snprintf.h>
extern "C" {
#include <dlfcn.h>
}
using namespace Genode;
enum { MAX_ERR = 128 };
static char err_str[MAX_ERR];
char *dlerror(void)
{
return err_str;
}
static Shared_object *to_object(void *handle)
{
return static_cast<Shared_object *>(handle);
}
void *dlopen(const char *name, int mode)
{
int supported = RTLD_LAZY | RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE;
/* error on unsupported mode values */
if (mode & ~supported) {
snprintf(err_str, MAX_ERR, "Unsupported mode 0x%x\n", mode & ~supported);
PERR("dlopen: %s", err_str);
return nullptr;
}
Shared_object *obj = 0;
unsigned flags = mode & RTLD_NOW ? Shared_object::NOW : Shared_object::LAZY;
flags |= mode & RTLD_NODELETE ? Shared_object::KEEP : 0;
try {
obj = new (env()->heap()) Shared_object(name, flags);
} catch (...) {
snprintf(err_str, MAX_ERR, "Unable to open file %s\n", name);
}
return (void *)obj;
}
void *dlsym(void *handle, const char *name)
{
if (handle == nullptr || handle == RTLD_NEXT || handle == RTLD_DEFAULT ||
handle == RTLD_SELF) {
snprintf(err_str, MAX_ERR, "Unsupported handle %p\n", handle);
return nullptr;
}
try {
return to_object(handle)->lookup(name);
} catch (...) {
snprintf(err_str, MAX_ERR, "Symbol '%s' not found\n", name);
}
return nullptr;
}
int dladdr(const void *addr, Dl_info *dlip)
{
try {
Address_info info((addr_t)addr);
dlip->dli_fname = info.path;
dlip->dli_fbase = (void *)info.base;
dlip->dli_sname = info.name;
dlip->dli_saddr = (void *)info.addr;
} catch (...) {
snprintf(err_str, MAX_ERR, "Symbol %p at not found", addr);
return 0;
}
return 1;
}
int dlclose(void *handle)
{
destroy(env()->heap(), to_object(handle));
return 0;
}
int dlinfo(void *handle, int request, void *p)
{
PERR("%s not implemented", __func__);
return 0;
}
dlfunc_t dlfunc(void *handle, const char *name)
{
PERR("%s not implemented", __func__);
return 0;
}
void *dlvsym(void *handle, const char *name, const char *version)
{
PERR("%s not implemented", __func__);
return nullptr;
}

View File

@ -0,0 +1 @@
LIBS = test-ldso_lib_dl

View File

@ -16,6 +16,7 @@
#define _TEST_LDSO_H_
void lib_1_test();
void lib_1_good();
void lib_1_exception();
void lib_2_exception();

View File

@ -0,0 +1,9 @@
#include <base/printf.h>
#include "test-ldso.h"
extern "C" void lib_dl_symbol()
{
Genode::printf("called (from '%s')\n", __func__);
Genode::printf("Call 'lib_1_good': ");
lib_1_good();
}

View File

@ -132,6 +132,34 @@ struct Test_stack_align_thread : Thread<0x2000>
void entry() { test_stack_align("%f\n%g\n", 3.142, 2.718); }
};
/******************
** Dynamic cast **
******************/
struct Object_base
{
virtual void func() { printf("'Object_base' called: failed\n"); }
};
struct Object : Object_base
{
void func() { printf("'Object' called: good\n"); }
};
void test_dynamic_cast_call(Object_base *o)
{
Object *b = dynamic_cast<Object *>(o);
b->func();
}
static void test_dynamic_cast()
{
Object *o = new (Genode::env()->heap()) Object;
test_dynamic_cast_call(o);
}
/**
* Main function of LDSO test
*/
@ -188,7 +216,7 @@ int main(int argc, char **argv)
lib_1_test();
printf("test stack alignment\n");
printf("Test stack alignment\n");
printf("--------------------\n");
test_stack_align("%f\n%g\n", 3.142, 2.718);
Test_stack_align_thread t;
@ -196,6 +224,15 @@ int main(int argc, char **argv)
t.join();
printf("\n");
printf("Dynamic cast\n");
printf("------------\n");
test_dynamic_cast();
printf("\n");
printf("Destruction\n");
printf("-----------\n");
/* test if return value is propagated correctly by dynamic linker */
return 123;
}

View File

@ -1,12 +0,0 @@
REQUIRES = arm
SHARED_LIB = yes
DIR = $(REP_DIR)/src/lib/ldso
INC_DIR += $(DIR)/contrib/arm \
$(DIR)/include/libc/libc-arm \
$(DIR)/include/arm
vpath platform.c $(DIR)/arm
vpath % $(DIR)/contrib/arm
include $(DIR)/target.inc

View File

@ -1,7 +0,0 @@
SRC_CC = parent_cap.cc binary_name.cc
SRC_C = dummy.c
LIBS = syscall
vpath parent_cap.cc $(REP_DIR)/src/lib/ldso/arch
vpath binary_name.cc $(REP_DIR)/src/lib/ldso/arch
vpath dummy.c $(REP_DIR)/src/lib/ldso/arch/codezero

View File

@ -1,4 +0,0 @@
SRC_CC = parent_cap.cc binary_name.cc
vpath parent_cap.cc $(REP_DIR)/src/lib/ldso/arch
vpath binary_name.cc $(REP_DIR)/src/lib/ldso/arch

View File

@ -1,4 +0,0 @@
SRC_CC = parent_cap.cc binary_name.cc
vpath parent_cap.cc $(REP_DIR)/src/lib/ldso/arch/linux
vpath binary_name.cc $(REP_DIR)/src/lib/ldso/arch/linux

View File

@ -1,4 +0,0 @@
SRC_CC = parent_cap.cc binary_name.cc
vpath parent_cap.cc $(REP_DIR)/src/lib/ldso/arch/nova
vpath binary_name.cc $(REP_DIR)/src/lib/ldso/arch

View File

@ -1,5 +0,0 @@
SRC_CC = parent_cap.cc binary_name.cc
LIBS = l4
vpath parent_cap.cc $(REP_DIR)/src/lib/ldso/arch
vpath binary_name.cc $(REP_DIR)/src/lib/ldso/arch

View File

@ -1,12 +0,0 @@
REQUIRES = x86 32bit
SHARED_LIB = yes
DIR = $(REP_DIR)/src/lib/ldso
INC_DIR += $(DIR)/contrib/i386 \
$(DIR)/include/libc/libc-i386 \
$(DIR)/include/x86_32
vpath % $(DIR)/contrib/i386
vpath % $(DIR)/x86_32
include $(DIR)/target.inc

View File

@ -1,14 +0,0 @@
REQUIRES = x86 64bit
SHARED_LIB = yes
DIR = $(REP_DIR)/src/lib/ldso
INC_DIR += $(DIR)/contrib/amd64 \
$(DIR)/include/libc/libc-amd64 \
$(DIR)/include/x86_64
D_OPTS = __ELF_WORD_SIZE=64
vpath % $(DIR)/contrib/amd64
include $(DIR)/target.inc

View File

@ -1,22 +0,0 @@
/*
* \brief Retrieve progam name from dataspace (Linux specific)
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-01-04
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <ldso/arch.h>
using namespace Genode;
/*
* Function is implemented for Linux/GDB only
*/
int Genode::binary_name(Dataspace_capability ds_cap, char *buf, size_t buf_size)
{
return -1;
}

View File

@ -1,22 +0,0 @@
/*
* \brief Dummies for Codezeros libmem (used by libl4)
* \author Sebastian Sumpf
* \date 2011-05-10
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
void *mem_cache_zalloc(void *cache){ return 0; }
void *mem_cache_alloc(void *cache){ return 0; }
void *mem_cache_init(void *start, int cache_size, int struct_size,
unsigned int alignment) { return 0; }
int mem_cache_free(void *cache, void *addr) { return 0; }
void *kmalloc(int size) { return 0; }

View File

@ -1,25 +0,0 @@
/*
* \brief Retrieve progam name from dataspace (Linux specific)
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-01-04
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <ldso/arch.h>
#include <linux_dataspace/client.h>
using namespace Genode;
int Genode::binary_name(Dataspace_capability ds_cap, char *buf, size_t buf_size)
{
/* determine name of binary to start */
Linux_dataspace_client ds_client(ds_cap);
Linux_dataspace::Filename filename = ds_client.fname();
strncpy(buf, filename.buf, buf_size);
return 0;
}

View File

@ -1,18 +0,0 @@
/*
* \brief Parent capability manipulation
* \author Sebastian Sumpf
* \date 2009-11-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <ldso/arch.h>
void Genode::set_parent_cap_arch(void *ptr)
{
}

View File

@ -1,21 +0,0 @@
/*
* \brief Parent capability manipulation
* \author Alexander Boettcher
* \date 2012-08-13
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <ldso/arch.h>
void Genode::set_parent_cap_arch(void *ptr)
{
/* Not required, determinig parent cap is done not using any exported
* symbols
*/
}

View File

@ -1,24 +0,0 @@
/*
* \brief Parent capability manipulation
* \author Sebastian Sumpf
* \date 2009-11-05
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/child.h>
#include <ldso/arch.h>
#include <util/string.h>
using namespace Genode;
void Genode::set_parent_cap_arch(void *ptr)
{
Genode::Parent_capability cap = parent_cap();
memcpy(ptr, &cap, sizeof(cap));
}

View File

@ -1,122 +0,0 @@
/*
* \brief Special handling for the ARM architecture
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-07-05
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include "rtld.h"
#include <fcntl.h>
#include <machine/elf.h>
#include <sys/param.h>
#include <unistd.h>
#include "dl_extensions.h"
/*
* cbass: Added EHABI exception table section type
*
*/
#ifndef PT_ARM_EXIDX
#define PT_ARM_EXIDX 0x70000001
#endif
extern Obj_Entry *obj_list;
typedef struct exidx_t {
unsigned long base;
int count;
} exidx_t;
/*
* Scan for exception index section and parse information
*/
static void platform_section(Elf_Phdr *phdr, void **priv)
{
exidx_t *exidx;
switch (phdr->p_type) {
case PT_ARM_EXIDX:
exidx = (exidx_t *)xmalloc(sizeof(exidx_t));
exidx->base = phdr->p_vaddr;
/* Each exception table entry is 8 Byte */
exidx->count = phdr->p_memsz / 8;
*priv = (void *)exidx;
return;
}
}
/*
* Read program header and setup exception information
*/
static void find_exidx(Obj_Entry *obj)
{
char *phdr = file_phdr(obj->path, (void *)obj->mapbase);
Elf_Ehdr *ehdr = (Elf_Ehdr *)phdr;
Elf_Phdr *ph_table = (Elf_Phdr *)(phdr + ehdr->e_phoff);
unsigned i;
size_t start = ~0;
size_t end = ~0;
for (i = 0; i < ehdr->e_phnum; i++) {
platform_section(&ph_table[i], &obj->priv);
/* determine map size */
if (ph_table[i].p_type == PT_LOAD) {
if (start == ~0)
start = trunc_page(ph_table[i].p_vaddr);
end = round_page(ph_table[i].p_vaddr + ph_table[i].p_memsz);
}
}
/* since linker is not setup by map_object map info is not set correctly */
if (obj->rtld) {
obj->vaddrbase = (Elf_Addr)obj->mapbase;
obj->mapsize = end - start;
}
}
/*
* Find exceptions index that matches given IP (PC)
*/
unsigned long dl_unwind_find_exidx(unsigned long pc, int *pcount)
{
Obj_Entry *obj;
extern Obj_Entry obj_rtld;
caddr_t addr = (caddr_t)pc;
/*
* Used during startup before ldso's main function is called and therefore
* obj_list has not been initialized
*/
Obj_Entry *list = obj_list;
if (!list)
list = &obj_rtld;
for (obj = list; obj != NULL; obj = obj->next) {
/* initialize exceptions for object */
if (!obj->priv)
find_exidx(obj);
if (addr >= obj->mapbase && addr < obj->mapbase + obj->mapsize && obj->priv) {
*pcount = ((exidx_t *)obj->priv)->count;
return (unsigned long)(((exidx_t *)obj->priv)->base + obj->mapbase - obj->vaddrbase);
}
}
*pcount = 0;
return 0;
}

View File

@ -1,58 +0,0 @@
/*
* \brief Call the main function of the dynamic program
* \author Martin Stein
* \date 2013-12-14
*/
/*
* Copyright (C) 2014 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
typedef void (*Func)(void);
int genode_atexit(Func);
extern "C" { void const ** get_program_var_addr(char const * name); }
extern char ** genode_argv;
extern int genode_argc;
extern char ** genode_envp;
/**
* Cast a given function pointer into a 'void (*)()' function pointer
*
* \param ptr source function pointer
*/
template <typename Func_ptr>
static Func * func(Func_ptr ptr)
{
return reinterpret_cast<Func *>(const_cast<void **>(ptr));
}
/**
* Call the main function of the dynamic program
*
* \param main_ptr raw pointer of program main-function
*
* \return return value of the program main-function
*/
extern "C" int call_program_main(Func main_func)
{
/* call constructors of global objects of the program */
Func * const _ctors_end = func(get_program_var_addr("_ctors_end"));
Func * const _ctors_start = func(get_program_var_addr("_ctors_start"));
for (Func * ctor = _ctors_end; ctor != _ctors_start; (*--ctor)());
/* register global-object destructors of program at LDSO atexit-array */
Func * const _dtors_end = func(get_program_var_addr("_dtors_end"));
Func * const _dtors_start = func(get_program_var_addr("_dtors_start"));
for (Func * dtor = _dtors_start; dtor != _dtors_end; genode_atexit(*dtor++));
/* call main function of the program */
typedef int (*Main)(int, char **, char **);
Main const main = reinterpret_cast<Main>(main_func);
return main(genode_argc, genode_argv, genode_envp);
}

View File

@ -1,407 +0,0 @@
/*-
* Copyright 1996, 1997, 1998, 1999 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/amd64/reloc.c,v 1.18.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Dynamic linker for ELF.
*
* John Polstra <jdp@polstra.com>.
*/
#include <sys/param.h>
#include <sys/mman.h>
#include <machine/sysarch.h>
#include <dlfcn.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#include "rtld.h"
/*
* Process the special R_X86_64_COPY relocations in the main program. These
* copy data from a shared object into a region in the main program's BSS
* segment.
*
* Returns 0 on success, -1 on failure.
*/
int
do_copy_relocations(Obj_Entry *dstobj)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
relalim = (const Elf_Rela *) ((caddr_t) dstobj->rela + dstobj->relasize);
for (rela = dstobj->rela; rela < relalim; rela++) {
if (ELF_R_TYPE(rela->r_info) == R_X86_64_COPY) {
void *dstaddr;
const Elf_Sym *dstsym;
const char *name;
unsigned long hash;
size_t size;
const void *srcaddr;
const Elf_Sym *srcsym;
Obj_Entry *srcobj;
const Ver_Entry *ve;
dstaddr = (void *) (dstobj->relocbase + rela->r_offset);
dstsym = dstobj->symtab + ELF_R_SYM(rela->r_info);
name = dstobj->strtab + dstsym->st_name;
hash = elf_hash(name);
size = dstsym->st_size;
ve = fetch_ventry(dstobj, ELF_R_SYM(rela->r_info));
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
if ((srcsym = symlook_obj(name, hash, srcobj, ve, 0)) != NULL)
break;
if (srcobj == NULL) {
_rtld_error("Undefined symbol \"%s\" referenced from COPY"
" relocation in %s", name, dstobj->path);
return -1;
}
srcaddr = (const void *) (srcobj->relocbase + srcsym->st_value);
memcpy(dstaddr, srcaddr, size);
}
}
return 0;
}
/* Initialize the special GOT entries. */
void
init_pltgot(Obj_Entry *obj)
{
if (obj->pltgot != NULL) {
obj->pltgot[1] = (Elf_Addr) obj;
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}
}
/* Process the non-PLT relocations. */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
SymCache *cache;
int bytes = obj->nchains * sizeof(SymCache);
int r = -1;
/*
* The dynamic loader may be called from a thread, we have
* limited amounts of stack available so we cannot use alloca().
*/
int flags = obj->rtld_init ? MAP_LDSO : 0;
cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON|flags, -1, 0);
if (cache == MAP_FAILED)
cache = NULL;
relalim = (const Elf_Rela *) ((caddr_t) obj->rela + obj->relasize);
for (rela = obj->rela; rela < relalim; rela++) {
Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rela->r_offset);
Elf32_Addr *where32 = (Elf32_Addr *)where;
switch (ELF_R_TYPE(rela->r_info)) {
case R_X86_64_NONE:
break;
case R_X86_64_64:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where = (Elf_Addr) (defobj->relocbase + def->st_value + rela->r_addend);
}
break;
case R_X86_64_PC32:
/*
* I don't think the dynamic linker should ever see this
* type of relocation. But the binutils-2.6 tools sometimes
* generate it.
*/
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where32 = (Elf32_Addr) (unsigned long) (defobj->relocbase +
def->st_value + rela->r_addend - (Elf_Addr) where);
}
break;
/* missing: R_X86_64_GOT32 R_X86_64_PLT32 */
case R_X86_64_COPY:
/*
* These are deferred until all other relocations have
* been done. All we do here is make sure that the COPY
* relocation is not in a shared library. They are allowed
* only in executable files.
*/
if (!obj->mainprog) {
_rtld_error("%s: Unexpected R_X86_64_COPY relocation"
" in shared library", obj->path);
goto done;
}
break;
case R_X86_64_GLOB_DAT:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
/* cbass: Skip undefined symbols */
if (def == NULL || defobj == NULL)
continue;
*where = (Elf_Addr) (defobj->relocbase + def->st_value);
}
break;
case R_X86_64_TPOFF64:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
/*
* We lazily allocate offsets for static TLS as we
* see the first relocation that references the
* TLS block. This allows us to support (small
* amounts of) static TLS in dynamically loaded
* modules. If we run out of space, we generate an
* error.
*/
if (!defobj->tls_done) {
if (!allocate_tls_offset((Obj_Entry*) defobj)) {
_rtld_error("%s: No space available for static "
"Thread Local Storage", obj->path);
goto done;
}
}
*where = (Elf_Addr) (def->st_value - defobj->tlsoffset +
rela->r_addend);
}
break;
case R_X86_64_TPOFF32:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
/*
* We lazily allocate offsets for static TLS as we
* see the first relocation that references the
* TLS block. This allows us to support (small
* amounts of) static TLS in dynamically loaded
* modules. If we run out of space, we generate an
* error.
*/
if (!defobj->tls_done) {
if (!allocate_tls_offset((Obj_Entry*) defobj)) {
_rtld_error("%s: No space available for static "
"Thread Local Storage", obj->path);
goto done;
}
}
*where32 = (Elf32_Addr) (def->st_value -
defobj->tlsoffset +
rela->r_addend);
}
break;
case R_X86_64_DTPMOD64:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where += (Elf_Addr) defobj->tlsindex;
}
break;
case R_X86_64_DTPOFF64:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where += (Elf_Addr) (def->st_value + rela->r_addend);
}
break;
case R_X86_64_DTPOFF32:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where32 += (Elf32_Addr) (def->st_value + rela->r_addend);
}
break;
case R_X86_64_RELATIVE:
*where = (Elf_Addr)(obj->relocbase + rela->r_addend);
break;
/* missing: R_X86_64_GOTPCREL, R_X86_64_32, R_X86_64_32S, R_X86_64_16, R_X86_64_PC16, R_X86_64_8, R_X86_64_PC8 */
default:
_rtld_error("%s: Unsupported relocation type %u"
" in non-PLT relocations\n", obj->path,
(unsigned int)ELF_R_TYPE(rela->r_info));
goto done;
}
}
r = 0;
done:
/*
* Do not unmap if LDSO is in initialization, since some ctors might not
* be called, yet.
*/
if (cache && !(obj->rtld_init))
munmap(cache, bytes);
return(r);
}
/* Process the PLT relocations. */
int
reloc_plt(Obj_Entry *obj)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
Elf_Addr *where;
assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT);
/* Relocate the GOT slot pointing into the PLT. */
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
*where += (Elf_Addr)obj->relocbase;
}
return 0;
}
/* Relocate the jump slots in an object. */
int
reloc_jmpslots(Obj_Entry *obj)
{
const Elf_Rela *relalim;
const Elf_Rela *rela;
if (obj->jmpslots_done)
return 0;
relalim = (const Elf_Rela *)((char *)obj->pltrela + obj->pltrelasize);
for (rela = obj->pltrela; rela < relalim; rela++) {
Elf_Addr *where, target;
const Elf_Sym *def;
const Obj_Entry *defobj;
assert(ELF_R_TYPE(rela->r_info) == R_X86_64_JMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rela->r_offset);
def = find_symdef(ELF_R_SYM(rela->r_info), obj, &defobj, true, NULL);
if (def == NULL)
return -1;
target = (Elf_Addr)(defobj->relocbase + def->st_value + rela->r_addend);
reloc_jmpslot(where, target, defobj, obj, (const Elf_Rel *)rela);
}
obj->jmpslots_done = true;
return 0;
}
void
allocate_initial_tls(Obj_Entry *objs)
{
/*
* Fix the size of the static TLS block by using the maximum
* offset allocated so far and adding a bit for dynamic modules to
* use.
*/
tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA;
amd64_set_fsbase(allocate_tls(objs, 0,
3*sizeof(Elf_Addr), sizeof(Elf_Addr)));
}
void *__tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
Elf_Addr* dtv;
__asm __volatile("movq %%fs:0, %0" : "=r" (segbase));
dtv = segbase[1];
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
}

View File

@ -1,78 +0,0 @@
/*-
* Copyright (c) 1999, 2000 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/libexec/rtld-elf/amd64/rtld_machdep.h,v 1.13.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
#ifndef RTLD_MACHDEP_H
#define RTLD_MACHDEP_H 1
#include <sys/types.h>
#include <machine/atomic.h>
#define CACHE_LINE_SIZE 64
struct Struct_Obj_Entry;
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) \
((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC))
/* Fixup the jump slot at "where" to transfer control to "target". */
static inline Elf_Addr
reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
const struct Struct_Obj_Entry *obj,
const struct Struct_Obj_Entry *refobj, const Elf_Rel *rel)
{
#ifdef dbg
dbg("reloc_jmpslot: *%p = %p", (void *)(where),
(void *)(target));
#endif
(*(Elf_Addr *)(where) = (Elf_Addr)(target));
return target;
}
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
#define call_initfini_pointer(obj, target) \
(((InitFunc)(target))())
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
round(size, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round((prev_offset) + (size), align)
#define calculate_tls_end(off, size) (off)
typedef struct {
unsigned long ti_module;
unsigned long ti_offset;
} tls_index;
extern void *__tls_get_addr(tls_index *ti);
#endif

View File

@ -1,114 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/amd64/rtld_start.S,v 1.5.28.1 2009/04/15 03:14:26 kensmith Exp $
*/
.text
.align 4
.globl .rtld_start
.type .rtld_start,@function
.rtld_start:
xorq %rbp,%rbp # Clear frame pointer for good form
subq $24,%rsp # A place to store exit procedure addr
movq %rdi,%r12
movq %rsp,%rsi # save address of exit proc
movq %rsp,%rdx # construct address of obj_main
addq $8,%rdx
call _rtld@PLT # Call rtld(sp); returns entry point
popq %rsi # Get exit procedure address
movq %r12,%rdi # *ap
/*
* At this point, %rax contains the entry point of the main program, and
* %rdx contains a pointer to a termination function that should be
* registered with atexit(). (crt1.o registers it.)
*/
.globl .rtld_goto_main
.rtld_goto_main: # This symbol exists just to make debugging easier.
jmp *%rax # Enter main program
/*
* Binder entry point. Control is transferred to here by code in the PLT.
* On entry, there are two arguments on the stack. In ascending address
* order, they are (1) "obj", a pointer to the calling object's Obj_Entry,
* and (2) "reloff", the byte offset of the appropriate relocation entry
* in the PLT relocation table.
*
* We are careful to preserve all registers, even the the caller-save
* registers. That is because this code may be invoked by low-level
* assembly-language code that is not ABI-compliant.
*
* Stack map:
* reloff 0x60
* obj 0x58
* spare 0x50
* rflags 0x48
* rax 0x40
* rdx 0x38
* rcx 0x30
* rsi 0x28
* rdi 0x20
* r8 0x18
* r9 0x10
* r10 0x8
* r11 0x0
*/
.align 4
.globl _rtld_bind_start
.type _rtld_bind_start,@function
_rtld_bind_start:
subq $8,%rsp
pushfq # Save rflags
pushq %rax # Save %rax
pushq %rdx # Save %rdx
pushq %rcx # Save %rcx
pushq %rsi # Save %rsi
pushq %rdi # Save %rdi
pushq %r8 # Save %r8
pushq %r9 # Save %r9
pushq %r10 # Save %r10
pushq %r11 # Save %r11
movq 0x58(%rsp),%rdi # Fetch obj argument
movq 0x60(%rsp),%rsi # Fetch reloff argument
leaq (%rsi,%rsi,2),%rsi # multiply by 3
leaq (,%rsi,8),%rsi # now 8, for 24 (sizeof Elf_Rela)
call _rtld_bind@PLT # Transfer control to the binder
/* Now %rax contains the entry point of the function being called. */
movq %rax,0x60(%rsp) # Store target over reloff argument
popq %r11 # Restore %r11
popq %r10 # Restore %r10
popq %r9 # Restore %r9
popq %r8 # Restore %r8
popq %rdi # Restore %rdi
popq %rsi # Restore %rsi
popq %rcx # Restore %rcx
popq %rdx # Restore %rdx
popq %rax # Restore %rax
popfq # Restore rflags
leaq 16(%rsp),%rsp # Discard spare, obj, do not change rflags
ret # "Return" to target address

View File

@ -1,398 +0,0 @@
/* $NetBSD: mdreloc.c,v 1.23 2003/07/26 15:04:38 mrg Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/libexec/rtld-elf/arm/reloc.c,v 1.4.8.1 2009/04/15 03:14:26 kensmith Exp $");
#include <sys/param.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#include "rtld.h"
void
init_pltgot(Obj_Entry *obj)
{
if (obj->pltgot != NULL) {
obj->pltgot[1] = (Elf_Addr) obj;
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}
}
int
do_copy_relocations(Obj_Entry *dstobj)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
rellim = (const Elf_Rel *) ((caddr_t) dstobj->rel + dstobj->relsize);
for (rel = dstobj->rel; rel < rellim; rel++) {
if (ELF_R_TYPE(rel->r_info) == R_ARM_COPY) {
void *dstaddr;
const Elf_Sym *dstsym;
const char *name;
unsigned long hash;
size_t size;
const void *srcaddr;
const Elf_Sym *srcsym;
Obj_Entry *srcobj;
const Ver_Entry *ve;
dstaddr = (void *) (dstobj->relocbase + rel->r_offset);
dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info);
name = dstobj->strtab + dstsym->st_name;
hash = elf_hash(name);
size = dstsym->st_size;
ve = fetch_ventry(dstobj, ELF_R_SYM(rel->r_info));
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
if ((srcsym = symlook_obj(name, hash, srcobj, ve, 0)) != NULL)
break;
if (srcobj == NULL) {
_rtld_error("Undefined symbol \"%s\" referenced from COPY"
" relocation in %s", name, dstobj->path);
return -1;
}
srcaddr = (const void *) (srcobj->relocbase + srcsym->st_value);
memcpy(dstaddr, srcaddr, size);
}
}
return 0;
}
void _rtld_bind_start(void);
void _rtld_relocate_nonplt_self(Elf_Dyn *, Elf_Addr);
int open();
int _open();
void
_rtld_relocate_nonplt_self(Elf_Dyn *dynp, Elf_Addr relocbase)
{
const Elf_Rel *rel = 0, *rellim;
Elf_Addr relsz = 0;
Elf_Addr *where;
for (; dynp->d_tag != DT_NULL; dynp++) {
switch (dynp->d_tag) {
case DT_REL:
rel = (const Elf_Rel *)(relocbase + dynp->d_un.d_ptr);
break;
case DT_RELSZ:
relsz = dynp->d_un.d_val;
break;
}
}
rellim = (const Elf_Rel *)((caddr_t)rel + relsz);
for (; rel < rellim; rel++) {
where = (Elf_Addr *)(relocbase + rel->r_offset);
*where += (Elf_Addr)relocbase;
}
}
/*
* It is possible for the compiler to emit relocations for unaligned data.
* We handle this situation with these inlines.
*/
#define RELOC_ALIGNED_P(x) \
(((uintptr_t)(x) & (sizeof(void *) - 1)) == 0)
static __inline Elf_Addr
load_ptr(void *where)
{
Elf_Addr res;
memcpy(&res, where, sizeof(res));
return (res);
}
static __inline void
store_ptr(void *where, Elf_Addr val)
{
memcpy(where, &val, sizeof(val));
}
static int
reloc_nonplt_object(Obj_Entry *obj, const Elf_Rel *rel, SymCache *cache)
{
Elf_Addr *where;
const Elf_Sym *def;
const Obj_Entry *defobj;
Elf_Addr tmp;
unsigned long symnum;
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
symnum = ELF_R_SYM(rel->r_info);
/*
* cbass:
* This is the second relocation run for LDSO, relocate global
* symbols only, in order to resolve e.g. type informations in
* binary
*/
if (obj->rtld && !(obj->rtld_init)) {
switch (ELF_R_TYPE(rel->r_info)) {
case R_ARM_GLOB_DAT: /* word32 B + S */
def = find_symdef(symnum, obj, &defobj, false, cache);
if (def == NULL || defobj==NULL)
return 0;
*where = (Elf_Addr)defobj->relocbase +
def->st_value;
default:
return 0;
}
}
switch (ELF_R_TYPE(rel->r_info)) {
case R_ARM_NONE:
/* XXX cbass: Ignore TLS relocations */
case R_ARM_TLS_DTPMOD32:
break;
#if 1 /* XXX should not occur */
case R_ARM_PC24: { /* word32 S - P + A */
Elf32_Sword addend;
/*
* Extract addend and sign-extend if needed.
*/
addend = *where;
if (addend & 0x00800000)
addend |= 0xff000000;
def = find_symdef(symnum, obj, &defobj, false, cache);
if (def == NULL)
return -1;
tmp = (Elf_Addr)obj->relocbase + def->st_value
- (Elf_Addr)where + (addend << 2);
if ((tmp & 0xfe000000) != 0xfe000000 &&
(tmp & 0xfe000000) != 0) {
_rtld_error(
"%s: R_ARM_PC24 relocation @ %p to %s failed "
"(displacement %ld (%#lx) out of range)",
obj->path, where,
obj->strtab + obj->symtab[symnum].st_name,
(long) tmp, (long) tmp);
return -1;
}
tmp >>= 2;
*where = (*where & 0xff000000) | (tmp & 0x00ffffff);
dbg("PC24 %s in %s --> %p @ %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)*where, where, defobj->path);
break;
}
#endif
case R_ARM_REL32: /* word32 S - P + A */
def = find_symdef(symnum, obj, &defobj, false, cache);
if (def == NULL)
return -1;
*where = (Elf_Addr)defobj->relocbase + def->st_value - (Elf_Addr)where
+ *where;
break;
case R_ARM_ABS32: /* word32 B + S + A */
case R_ARM_GLOB_DAT: /* word32 B + S */
def = find_symdef(symnum, obj, &defobj, false, cache);
/* cbass: Skip undefined symbols */
if (def == NULL || defobj==NULL)
return 0;
if (__predict_true(RELOC_ALIGNED_P(where))) {
tmp = *where + (Elf_Addr)defobj->relocbase +
def->st_value;
*where = tmp;
} else {
tmp = load_ptr(where) +
(Elf_Addr)defobj->relocbase +
def->st_value;
store_ptr(where, tmp);
}
dbg("ABS32/GLOB_DAT %s in %s --> %p @ %p in %s",
obj->strtab + obj->symtab[symnum].st_name,
obj->path, (void *)tmp, where, defobj->path);
break;
case R_ARM_RELATIVE: /* word32 B + A */
if (__predict_true(RELOC_ALIGNED_P(where))) {
tmp = *where + (Elf_Addr)obj->relocbase;
if (obj->relocbase)
*where = tmp;
} else {
tmp = load_ptr(where) +
(Elf_Addr)obj->relocbase;
store_ptr(where, tmp);
}
dbg("RELATIVE in %s --> %p", obj->path,
(void *)tmp);
break;
case R_ARM_COPY:
/*
* These are deferred until all other relocations have
* been done. All we do here is make sure that the
* COPY relocation is not in a shared library. They
* are allowed only in executable files.
*/
if (!obj->mainprog) {
_rtld_error(
"%s: Unexpected R_COPY relocation in shared library",
obj->path);
return -1;
}
dbg("COPY (avoid in main)");
break;
default:
dbg("sym = %lu, type = %lu, offset = %p, "
"contents = %p, symbol = %s",
symnum, (u_long)ELF_R_TYPE(rel->r_info),
(void *)rel->r_offset, (void *)load_ptr(where),
obj->strtab + obj->symtab[symnum].st_name);
_rtld_error("%s: Unsupported relocation type %ld "
"in non-PLT relocations\n",
obj->path, (u_long) ELF_R_TYPE(rel->r_info));
return -1;
}
return 0;
}
/*
* * Process non-PLT relocations
* */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
SymCache *cache;
int bytes = obj->nchains * sizeof(SymCache);
int r = -1;
/*
* The dynamic loader may be called from a thread, we have
* limited amounts of stack available so we cannot use alloca().
*/
int flags = obj->rtld_init ? MAP_LDSO : 0;
cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON|flags, -1, 0);
if (cache == MAP_FAILED)
cache = NULL;
rellim = (const Elf_Rel *)((caddr_t)obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
if (reloc_nonplt_object(obj, rel, cache) < 0)
goto done;
}
r = 0;
done:
/*
* Do not unmap if LDSO is in initialization, since some ctors might not
* be called, yet.
*/
if (cache && !(obj->rtld_init)) {
munmap(cache, bytes);
}
return (r);
}
/*
* * Process the PLT relocations.
* */
int
reloc_plt(Obj_Entry *obj)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
rellim = (const Elf_Rel *)((char *)obj->pltrel +
obj->pltrelsize);
for (rel = obj->pltrel; rel < rellim; rel++) {
Elf_Addr *where;
assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
*where += (Elf_Addr )obj->relocbase;
}
return (0);
}
/*
* * LD_BIND_NOW was set - force relocation for all jump slots
* */
int
reloc_jmpslots(Obj_Entry *obj)
{
const Obj_Entry *defobj;
const Elf_Rel *rellim;
const Elf_Rel *rel;
const Elf_Sym *def;
Elf_Addr *where;
Elf_Addr target;
rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
for (rel = obj->pltrel; rel < rellim; rel++) {
assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
true, NULL);
if (def == NULL) {
dbg("reloc_jmpslots: sym not found");
return (-1);
}
/* skip undefined symbols in linker */
if (defobj == NULL && obj->rtld)
continue;
target = (Elf_Addr)(defobj->relocbase + def->st_value);
reloc_jmpslot(where, target, defobj, obj,
(const Elf_Rel *) rel);
}
obj->jmpslots_done = true;
return (0);
}
Elf_Addr
reloc_jmpslot(Elf_Addr *where, Elf_Addr target, const Obj_Entry *defobj,
const Obj_Entry *obj, const Elf_Rel *rel)
{
assert(ELF_R_TYPE(rel->r_info) == R_ARM_JUMP_SLOT);
if (*where != target)
*where = target;
return target;
}
void
allocate_initial_tls(Obj_Entry *objs)
{
}
void *
__tls_get_addr(tls_index* ti)
{
/* XXX cbass: We don't support tls, but some compilers use TLS. Just for the
* sake of it: Provide some memory ... and best wishes!
*/
static char _tls[64];
return _tls;
}

View File

@ -1,74 +0,0 @@
/*-
* Copyright (c) 1999, 2000 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/libexec/rtld-elf/arm/rtld_machdep.h,v 1.5.20.1 2009/04/15 03:14:26 kensmith Exp $
*/
#ifndef RTLD_MACHDEP_H
#define RTLD_MACHDEP_H 1
#include <sys/types.h>
#include <machine/atomic.h>
#define CACHE_LINE_SIZE 32
struct Struct_Obj_Entry;
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) (&_DYNAMIC)
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
const struct Struct_Obj_Entry *defobj,
const struct Struct_Obj_Entry *obj,
const Elf_Rel *rel);
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
#define call_initfini_pointer(obj, target) \
(((InitFunc)(target))())
typedef struct {
unsigned long ti_module;
unsigned long ti_offset;
} tls_index;
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
round(size, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round(prev_offset + prev_size, align)
#define calculate_tls_end(off, size) ((off) + (size))
/*
* Lazy binding entry point, called via PLT.
*/
void _rtld_bind_start(void);
extern void *__tls_get_addr(tls_index *ti);
#endif

View File

@ -1,101 +0,0 @@
/* $NetBSD: rtld_start.S,v 1.7 2002/09/12 17:18:38 mycroft Exp $ */
/*-
* Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Matt Thomas and by Charles M. Hannum.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 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.
*/
#include <machine/asm.h>
__FBSDID("$FreeBSD: src/libexec/rtld-elf/arm/rtld_start.S,v 1.3.20.1 2009/04/15 03:14:26 kensmith Exp $");
.text
.align 0
.globl .rtld_start
.type .rtld_start,%function
.rtld_start:
sub sp, sp, #8 /* make room for obj_main & exit proc */
mov r4, r0 /* save ps_strings */
ldr sl, .L2
ldr r5, .L2+4
ldr r0, .L2+8
.L1:
add sl, pc, sl
ldr r5, [sl, r5]
ldr r0, [sl, r0]
sub r1, sl, r5 /* relocbase */
add r0, r1, r0 /* &_DYNAMIC */
bl _rtld_relocate_nonplt_self
mov r1, sp
add r2, sp, #4
add r0, sp, #8
bl _rtld /* call the shared loader */
mov r3, r0 /* save entry point */
ldr r2, [sp, #0] /* r2 = cleanup */
ldr r1, [sp, #4] /* r1 = obj_main */
add sp, sp, #8 /* restore stack */
mov r0, r4 /* restore ps_strings */
mov pc, r3 /* jump to the entry point */
.L2:
.word _GLOBAL_OFFSET_TABLE_ - (.L1+8)
.word _GLOBAL_OFFSET_TABLE_(GOT)
.word _DYNAMIC(GOT)
.align 0
.globl _rtld_bind_start
.type _rtld_bind_start,%function
/*
* stack[0] = RA
* ip = &GOT[n+3]
* lr = &GOT[2]
*/
_rtld_bind_start:
stmdb sp!,{r0-r4,sl,fp}
sub r1, ip, lr /* r1 = 4 * (n + 1) */
sub r1, r1, #4 /* r1 = 4 * n */
add r1, r1, r1 /* r1 = 8 * n */
ldr r0, [lr, #-4] /* get obj ptr from GOT[1] */
mov r4, ip /* save GOT location */
bl _rtld_bind /* Call the binder */
str r0, [r4] /* save address in GOT */
mov ip, r0 /* save new address */
ldmia sp!,{r0-r4,sl,fp,lr} /* restore the stack */
mov pc, ip /* jump to the new address */

View File

@ -1,143 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/debug.c,v 1.4.30.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Support for printing debugging messages.
*/
#include <stdarg.h>
#include <stdio.h>
#include "debug.h"
#include "rtld.h"
static const char rel_header[] =
" symbol name r_info r_offset st_value st_size address value\n"
" ------------------------------------------------------------------------------\n";
static const char rel_format[] = " %-25s %6lx %08lx %08lx %7d %10p %08lx\n";
int debug = 0;
void
debug_printf(const char *format, ...)
{
if (debug) {
va_list ap;
va_start(ap, format);
fflush(stdout);
vfprintf(stderr, format, ap);
putc('\n', stderr);
va_end(ap);
}
}
void
dump_relocations (Obj_Entry *obj0)
{
Obj_Entry *obj;
for (obj = obj0; obj != NULL; obj = obj->next) {
dump_obj_relocations(obj);
}
}
void
dump_obj_relocations (Obj_Entry *obj)
{
printf("Object \"%s\", relocbase %p\n", obj->path, obj->relocbase);
if (obj->relsize) {
printf("Non-PLT Relocations: %ld\n",
(obj->relsize / sizeof(Elf_Rel)));
dump_Elf_Rel(obj, obj->rel, obj->relsize);
}
if (obj->relasize) {
printf("Non-PLT Relocations with Addend: %ld\n",
(obj->relasize / sizeof(Elf_Rela)));
dump_Elf_Rela(obj, obj->rela, obj->relasize);
}
if (obj->pltrelsize) {
printf("PLT Relocations: %ld\n",
(obj->pltrelsize / sizeof(Elf_Rel)));
dump_Elf_Rel(obj, obj->pltrel, obj->pltrelsize);
}
if (obj->pltrelasize) {
printf("PLT Relocations with Addend: %ld\n",
(obj->pltrelasize / sizeof(Elf_Rela)));
dump_Elf_Rela(obj, obj->pltrela, obj->pltrelasize);
}
}
void
dump_Elf_Rel (Obj_Entry *obj, const Elf_Rel *rel0, u_long relsize)
{
const Elf_Rel *rel;
const Elf_Rel *rellim;
const Elf_Sym *sym;
Elf_Addr *dstaddr;
printf("%s", rel_header);
rellim = (const Elf_Rel *)((const char *)rel0 + relsize);
for (rel = rel0; rel < rellim; rel++) {
dstaddr = (Elf_Addr *)(obj->relocbase + rel->r_offset);
sym = obj->symtab + ELF_R_SYM(rel->r_info);
printf(rel_format,
obj->strtab + sym->st_name,
(u_long)rel->r_info, (u_long)rel->r_offset,
(u_long)sym->st_value, (int)sym->st_size,
dstaddr, (u_long)*dstaddr);
}
return;
}
void
dump_Elf_Rela (Obj_Entry *obj, const Elf_Rela *rela0, u_long relasize)
{
const Elf_Rela *rela;
const Elf_Rela *relalim;
const Elf_Sym *sym;
Elf_Addr *dstaddr;
printf("%s", rel_header);
relalim = (const Elf_Rela *)((const char *)rela0 + relasize);
for (rela = rela0; rela < relalim; rela++) {
dstaddr = (Elf_Addr *)(obj->relocbase + rela->r_offset);
sym = obj->symtab + ELF_R_SYM(rela->r_info);
printf(rel_format,
obj->strtab + sym->st_name,
(u_long)rela->r_info, (u_long)rela->r_offset,
(u_long)sym->st_value, (int)sym->st_size,
dstaddr, (u_long)*dstaddr);
}
return;
}

View File

@ -1,66 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/debug.h,v 1.7.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Support for printing debugging messages.
*/
#ifndef DEBUG_H
#define DEBUG_H 1
#ifndef __GNUC__
#error "This file must be compiled with GCC"
#endif
#include <sys/cdefs.h>
#include <string.h>
#include <unistd.h>
extern void debug_printf(const char *, ...) __printflike(1, 2);
extern int debug;
#ifdef DEBUG
#define dbg(...) debug_printf(__VA_ARGS__)
#else
#define dbg(...) ((void) 0)
#endif
#ifndef COMPAT_32BIT
#define _MYNAME "ld-elf.so.1"
#else
#define _MYNAME "ld-elf32.so.1"
#endif
#define assert(cond) ((cond) ? (void) 0 : \
(msg(_MYNAME ": assert failed: " __FILE__ ":" \
__XSTRING(__LINE__) "\n"), abort()))
#define msg(s) write(STDOUT_FILENO, s, strlen(s))
#define trace() msg(_MYNAME ": " __XSTRING(__LINE__) "\n")
#endif /* DEBUG_H */

View File

@ -1,387 +0,0 @@
/*-
* Copyright 1996, 1997, 1998, 1999 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/i386/reloc.c,v 1.20.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Dynamic linker for ELF.
*
* John Polstra <jdp@polstra.com>.
*/
#include <sys/param.h>
#include <sys/mman.h>
#include <machine/segments.h>
#include <machine/sysarch.h>
#include <dlfcn.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#include "rtld.h"
/*
* Process the special R_386_COPY relocations in the main program. These
* copy data from a shared object into a region in the main program's BSS
* segment.
*
* Returns 0 on success, -1 on failure.
*/
int
do_copy_relocations(Obj_Entry *dstobj)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
assert(dstobj->mainprog); /* COPY relocations are invalid elsewhere */
rellim = (const Elf_Rel *) ((caddr_t) dstobj->rel + dstobj->relsize);
for (rel = dstobj->rel; rel < rellim; rel++) {
if (ELF_R_TYPE(rel->r_info) == R_386_COPY) {
void *dstaddr;
const Elf_Sym *dstsym;
const char *name;
unsigned long hash;
size_t size;
const void *srcaddr;
const Elf_Sym *srcsym;
const Ver_Entry *ve;
Obj_Entry *srcobj;
dstaddr = (void *) (dstobj->relocbase + rel->r_offset);
dstsym = dstobj->symtab + ELF_R_SYM(rel->r_info);
name = dstobj->strtab + dstsym->st_name;
hash = elf_hash(name);
size = dstsym->st_size;
ve = fetch_ventry(dstobj, ELF_R_SYM(rel->r_info));
for (srcobj = dstobj->next; srcobj != NULL; srcobj = srcobj->next)
if ((srcsym = symlook_obj(name, hash, srcobj, ve, 0)) != NULL)
break;
if (srcobj == NULL) {
_rtld_error("Undefined symbol \"%s\" referenced from COPY"
" relocation in %s", name, dstobj->path);
return -1;
}
srcaddr = (const void *) (srcobj->relocbase + srcsym->st_value);
memcpy(dstaddr, srcaddr, size);
}
}
return 0;
}
/* Initialize the special GOT entries. */
void
init_pltgot(Obj_Entry *obj)
{
if (obj->pltgot != NULL) {
obj->pltgot[1] = (Elf_Addr) obj;
obj->pltgot[2] = (Elf_Addr) &_rtld_bind_start;
}
}
/* Process the non-PLT relocations. */
int
reloc_non_plt(Obj_Entry *obj, Obj_Entry *obj_rtld)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
SymCache *cache;
int bytes = obj->nchains * sizeof(SymCache);
int r = -1;
/*
* The dynamic loader may be called from a thread, we have
* limited amounts of stack available so we cannot use alloca().
*/
int flags = obj->rtld_init ? MAP_LDSO : 0;
cache = mmap(NULL, bytes, PROT_READ|PROT_WRITE, MAP_ANON|flags, -1, 0);
if (cache == MAP_FAILED)
cache = NULL;
rellim = (const Elf_Rel *) ((caddr_t) obj->rel + obj->relsize);
for (rel = obj->rel; rel < rellim; rel++) {
Elf_Addr *where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
/*
* cbass:
* This is the second relocation run for LDSO, relocate global
* symbols only, in order to resolve e.g. type informations in
* binary
*/
if (obj->rtld && !obj->rtld_init) {
switch (ELF_R_TYPE(rel->r_info)) {
case R_386_GLOB_DAT:
break;
default:
continue;
}
}
switch (ELF_R_TYPE(rel->r_info)) {
case R_386_NONE:
break;
case R_386_32:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where += (Elf_Addr) (defobj->relocbase + def->st_value);
}
break;
case R_386_PC32:
/*
* I don't think the dynamic linker should ever see this
* type of relocation. But the binutils-2.6 tools sometimes
* generate it.
*/
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where +=
(Elf_Addr) (defobj->relocbase + def->st_value) -
(Elf_Addr) where;
}
break;
case R_386_COPY:
/*
* These are deferred until all other relocations have
* been done. All we do here is make sure that the COPY
* relocation is not in a shared library. They are allowed
* only in executable files.
*/
if (!obj->mainprog) {
_rtld_error("%s: Unexpected R_386_COPY relocation"
" in shared library", obj->path);
goto done;
}
break;
case R_386_GLOB_DAT:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
/* cbass: Skip undefined symbols */
if (def == NULL || defobj == NULL)
continue;
*where = (Elf_Addr) (defobj->relocbase + def->st_value);
}
break;
case R_386_RELATIVE:
/* skip text relocations for ld.lib.so, since relocbase is 0
* here */
if (!obj->rtld)
*where += (Elf_Addr) obj->relocbase;
break;
case R_386_TLS_TPOFF:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
/*
* We lazily allocate offsets for static TLS as we
* see the first relocation that references the
* TLS block. This allows us to support (small
* amounts of) static TLS in dynamically loaded
* modules. If we run out of space, we generate an
* error.
*/
if (!defobj->tls_done) {
if (!allocate_tls_offset((Obj_Entry*) defobj)) {
_rtld_error("%s: No space available for static "
"Thread Local Storage", obj->path);
goto done;
}
}
*where += (Elf_Addr) (def->st_value - defobj->tlsoffset);
}
break;
case R_386_TLS_DTPMOD32:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where += (Elf_Addr) defobj->tlsindex;
}
break;
case R_386_TLS_DTPOFF32:
{
const Elf_Sym *def;
const Obj_Entry *defobj;
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj,
false, cache);
if (def == NULL)
goto done;
*where += (Elf_Addr) def->st_value;
}
break;
default:
_rtld_error("%s: Unsupported relocation type %d"
" in non-PLT relocations\n", obj->path,
ELF_R_TYPE(rel->r_info));
goto done;
}
}
r = 0;
done:
/*
* Do not unmap if LDSO is in initialization, since some ctors might not
* be called, yet.
*/
if (cache && !(obj->rtld_init))
munmap(cache, bytes);
return(r);
}
/* Process the PLT relocations. */
int
reloc_plt(Obj_Entry *obj)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
for (rel = obj->pltrel; rel < rellim; rel++) {
Elf_Addr *where;
assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT);
/* Relocate the GOT slot pointing into the PLT. */
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
*where += (Elf_Addr)obj->relocbase;
}
return 0;
}
/* Relocate the jump slots in an object. */
int
reloc_jmpslots(Obj_Entry *obj)
{
const Elf_Rel *rellim;
const Elf_Rel *rel;
if (obj->jmpslots_done)
return 0;
rellim = (const Elf_Rel *)((char *)obj->pltrel + obj->pltrelsize);
for (rel = obj->pltrel; rel < rellim; rel++) {
Elf_Addr *where, target;
const Elf_Sym *def;
const Obj_Entry *defobj;
assert(ELF_R_TYPE(rel->r_info) == R_386_JMP_SLOT);
where = (Elf_Addr *)(obj->relocbase + rel->r_offset);
def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
if (def == NULL)
return -1;
target = (Elf_Addr)(defobj->relocbase + def->st_value);
reloc_jmpslot(where, target, defobj, obj, rel);
}
obj->jmpslots_done = true;
return 0;
}
void
allocate_initial_tls(Obj_Entry *objs)
{
void* tls;
/*
* Fix the size of the static TLS block by using the maximum
* offset allocated so far and adding a bit for dynamic modules to
* use.
*/
tls_static_space = tls_last_offset + RTLD_STATIC_TLS_EXTRA;
tls = allocate_tls(objs, NULL, 3*sizeof(Elf_Addr), sizeof(Elf_Addr));
i386_set_gsbase(tls);
}
/* GNU ABI */
__attribute__((__regparm__(1)))
void *___tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
__asm __volatile("movl %%gs:0, %0" : "=r" (segbase));
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
}
/* Sun ABI */
void *__tls_get_addr(tls_index *ti)
{
Elf_Addr** segbase;
__asm __volatile("movl %%gs:0, %0" : "=r" (segbase));
return tls_get_addr_common(&segbase[1], ti->ti_module, ti->ti_offset);
}

View File

@ -1,79 +0,0 @@
/*-
* Copyright (c) 1999, 2000 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/libexec/rtld-elf/i386/rtld_machdep.h,v 1.11.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
#ifndef RTLD_MACHDEP_H
#define RTLD_MACHDEP_H 1
#include <sys/types.h>
#include <machine/atomic.h>
#define CACHE_LINE_SIZE 32
struct Struct_Obj_Entry;
/* Return the address of the .dynamic section in the dynamic linker. */
#define rtld_dynamic(obj) \
((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC))
/* Fixup the jump slot at "where" to transfer control to "target". */
static inline Elf_Addr
reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
const struct Struct_Obj_Entry *obj,
const struct Struct_Obj_Entry *refobj, const Elf_Rel *rel)
{
#ifdef dbg
dbg("reloc_jmpslot: *%p = %p", (void *)(where),
(void *)(target));
#endif
(*(Elf_Addr *)(where) = (Elf_Addr)(target));
return target;
}
#define make_function_pointer(def, defobj) \
((defobj)->relocbase + (def)->st_value)
#define call_initfini_pointer(obj, target) \
(((InitFunc)(target))())
#define round(size, align) \
(((size) + (align) - 1) & ~((align) - 1))
#define calculate_first_tls_offset(size, align) \
round(size, align)
#define calculate_tls_offset(prev_offset, prev_size, size, align) \
round((prev_offset) + (size), align)
#define calculate_tls_end(off, size) (off)
typedef struct {
unsigned long ti_module;
unsigned long ti_offset;
} tls_index;
extern void *___tls_get_addr(tls_index *ti) __attribute__((__regparm__(1)));
extern void *__tls_get_addr(tls_index *ti);
#endif

View File

@ -1,91 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/i386/rtld_start.S,v 1.4.20.1 2009/04/15 03:14:26 kensmith Exp $
*/
.text
.align 4
.globl .rtld_start
.type .rtld_start,@function
.rtld_start:
xorl %ebp,%ebp # Clear frame pointer for good form
movl %esp,%eax # Save initial stack pointer
movl %esp,%esi # Save initial stack pointer
andl $0xfffffff0,%esp # Align stack pointer
subl $16,%esp # A place to store exit procedure addr
movl %esp,%ebx # save address of exit proc
movl %esp,%ecx # construct address of obj_main
addl $4,%ecx
subl $4,%esp # Keep stack aligned
pushl %ecx # Pass address of obj_main
pushl %ebx # Pass address of exit proc
pushl %eax # Pass initial stack pointer to rtld
call _rtld@PLT # Call rtld(sp); returns entry point
addl $16,%esp # Remove arguments from stack
popl %edx # Get exit procedure address
movl %esi,%esp # Ignore obj_main
/*
* At this point, %eax contains the entry point of the main program, and
* %edx contains a pointer to a termination function that should be
* registered with atexit(). (crt1.o registers it.)
*/
.globl .rtld_goto_main
.rtld_goto_main: # This symbol exists just to make debugging easier.
jmp *%eax # Enter main program
/*
* Binder entry point. Control is transferred to here by code in the PLT.
* On entry, there are two arguments on the stack. In ascending address
* order, they are (1) "obj", a pointer to the calling object's Obj_Entry,
* and (2) "reloff", the byte offset of the appropriate relocation entry
* in the PLT relocation table.
*
* We are careful to preserve all registers, even the the caller-save
* registers. That is because this code may be invoked by low-level
* assembly-language code that is not ABI-compliant.
*/
.align 4
.globl _rtld_bind_start
.type _rtld_bind_start,@function
_rtld_bind_start:
pushf # Save eflags
pushl %eax # Save %eax
pushl %edx # Save %edx
pushl %ecx # Save %ecx
pushl 20(%esp) # Copy reloff argument
pushl 20(%esp) # Copy obj argument
call _rtld_bind@PLT # Transfer control to the binder
/* Now %eax contains the entry point of the function being called. */
addl $8,%esp # Discard binder arguments
movl %eax,20(%esp) # Store target over obj argument
popl %ecx # Restore %ecx
popl %edx # Restore %edx
popl %eax # Restore %eax
popf # Restore eflags
leal 4(%esp),%esp # Discard reloff, do not change eflags
ret # "Return" to target address

View File

@ -1,369 +0,0 @@
/*
* $FreeBSD: src/libexec/rtld-elf/libmap.c,v 1.15.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <sys/queue.h>
#include <sys/param.h>
#include "debug.h"
#include "rtld.h"
#include "libmap.h"
#ifndef _PATH_LIBMAP_CONF
#define _PATH_LIBMAP_CONF "/etc/libmap.conf"
#endif
#ifdef COMPAT_32BIT
#undef _PATH_LIBMAP_CONF
#define _PATH_LIBMAP_CONF "/etc/libmap32.conf"
#endif
TAILQ_HEAD(lm_list, lm);
struct lm {
char *f;
char *t;
TAILQ_ENTRY(lm) lm_link;
};
TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head);
struct lmp {
char *p;
enum { T_EXACT=0, T_BASENAME, T_DIRECTORY } type;
struct lm_list lml;
TAILQ_ENTRY(lmp) lmp_link;
};
static int lm_count;
static void lmc_parse (FILE *);
static void lm_add (const char *, const char *, const char *);
static void lm_free (struct lm_list *);
static char * lml_find (struct lm_list *, const char *);
static struct lm_list * lmp_find (const char *);
static struct lm_list * lmp_init (char *);
static const char * quickbasename (const char *);
static int readstrfn (void * cookie, char *buf, int len);
static int closestrfn (void * cookie);
#define iseol(c) (((c) == '#') || ((c) == '\0') || \
((c) == '\n') || ((c) == '\r'))
int
lm_init (char *libmap_override)
{
FILE *fp;
dbg("%s(\"%s\")", __func__, libmap_override);
TAILQ_INIT(&lmp_head);
fp = fopen(_PATH_LIBMAP_CONF, "r");
if (fp) {
lmc_parse(fp);
fclose(fp);
}
if (libmap_override) {
char *p;
/* do some character replacement to make $LIBMAP look like a
text file, then "open" it with funopen */
libmap_override = xstrdup(libmap_override);
for (p = libmap_override; *p; p++) {
switch (*p) {
case '=':
*p = ' '; break;
case ',':
*p = '\n'; break;
}
}
fp = funopen(libmap_override, readstrfn, NULL, NULL, closestrfn);
if (fp) {
lmc_parse(fp);
fclose(fp);
}
}
return (lm_count == 0);
}
static void
lmc_parse (FILE *fp)
{
char *cp;
char *f, *t, *c, *p;
char prog[MAXPATHLEN];
char line[MAXPATHLEN + 2];
dbg("%s(%p)", __func__, fp);
p = NULL;
while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
t = f = c = NULL;
/* Skip over leading space */
while (isspace(*cp)) cp++;
/* Found a comment or EOL */
if (iseol(*cp)) continue;
/* Found a constraint selector */
if (*cp == '[') {
cp++;
/* Skip leading space */
while (isspace(*cp)) cp++;
/* Found comment, EOL or end of selector */
if (iseol(*cp) || *cp == ']')
continue;
c = cp++;
/* Skip to end of word */
while (!isspace(*cp) && !iseol(*cp) && *cp != ']')
cp++;
/* Skip and zero out trailing space */
while (isspace(*cp)) *cp++ = '\0';
/* Check if there is a closing brace */
if (*cp != ']') continue;
/* Terminate string if there was no trailing space */
*cp++ = '\0';
/*
* There should be nothing except whitespace or comment
from this point to the end of the line.
*/
while(isspace(*cp)) cp++;
if (!iseol(*cp)) continue;
strcpy(prog, c);
p = prog;
continue;
}
/* Parse the 'from' candidate. */
f = cp++;
while (!isspace(*cp) && !iseol(*cp)) cp++;
/* Skip and zero out the trailing whitespace */
while (isspace(*cp)) *cp++ = '\0';
/* Found a comment or EOL */
if (iseol(*cp)) continue;
/* Parse 'to' mapping */
t = cp++;
while (!isspace(*cp) && !iseol(*cp)) cp++;
/* Skip and zero out the trailing whitespace */
while (isspace(*cp)) *cp++ = '\0';
/* Should be no extra tokens at this point */
if (!iseol(*cp)) continue;
*cp = '\0';
lm_add(p, f, t);
}
}
static void
lm_free (struct lm_list *lml)
{
struct lm *lm;
dbg("%s(%p)", __func__, lml);
while (!TAILQ_EMPTY(lml)) {
lm = TAILQ_FIRST(lml);
TAILQ_REMOVE(lml, lm, lm_link);
free(lm->f);
free(lm->t);
free(lm);
}
return;
}
void
lm_fini (void)
{
struct lmp *lmp;
dbg("%s()", __func__);
while (!TAILQ_EMPTY(&lmp_head)) {
lmp = TAILQ_FIRST(&lmp_head);
TAILQ_REMOVE(&lmp_head, lmp, lmp_link);
free(lmp->p);
lm_free(&lmp->lml);
free(lmp);
}
return;
}
static void
lm_add (const char *p, const char *f, const char *t)
{
struct lm_list *lml;
struct lm *lm;
if (p == NULL)
p = "$DEFAULT$";
dbg("%s(\"%s\", \"%s\", \"%s\")", __func__, p, f, t);
if ((lml = lmp_find(p)) == NULL)
lml = lmp_init(xstrdup(p));
lm = xmalloc(sizeof(struct lm));
lm->f = xstrdup(f);
lm->t = xstrdup(t);
TAILQ_INSERT_HEAD(lml, lm, lm_link);
lm_count++;
}
char *
lm_find (const char *p, const char *f)
{
struct lm_list *lml;
char *t;
dbg("%s(\"%s\", \"%s\")", __func__, p, f);
if (p != NULL && (lml = lmp_find(p)) != NULL) {
t = lml_find(lml, f);
if (t != NULL) {
/*
* Add a global mapping if we have
* a successful constrained match.
*/
lm_add(NULL, f, t);
return (t);
}
}
lml = lmp_find("$DEFAULT$");
if (lml != NULL)
return (lml_find(lml, f));
else
return (NULL);
}
/* Given a libmap translation list and a library name, return the
replacement library, or NULL */
#ifdef COMPAT_32BIT
char *
lm_findn (const char *p, const char *f, const int n)
{
char pathbuf[64], *s, *t;
if (n < sizeof(pathbuf) - 1)
s = pathbuf;
else
s = xmalloc(n + 1);
memcpy(s, f, n);
s[n] = '\0';
t = lm_find(p, s);
if (s != pathbuf)
free(s);
return (t);
}
#endif
static char *
lml_find (struct lm_list *lmh, const char *f)
{
struct lm *lm;
dbg("%s(%p, \"%s\")", __func__, lmh, f);
TAILQ_FOREACH(lm, lmh, lm_link)
if (strcmp(f, lm->f) == 0)
return (lm->t);
return (NULL);
}
/* Given an executable name, return a pointer to the translation list or
NULL if no matches */
static struct lm_list *
lmp_find (const char *n)
{
struct lmp *lmp;
dbg("%s(\"%s\")", __func__, n);
TAILQ_FOREACH(lmp, &lmp_head, lmp_link)
if ((lmp->type == T_EXACT && strcmp(n, lmp->p) == 0) ||
(lmp->type == T_DIRECTORY && strncmp(n, lmp->p, strlen(lmp->p)) == 0) ||
(lmp->type == T_BASENAME && strcmp(quickbasename(n), lmp->p) == 0))
return (&lmp->lml);
return (NULL);
}
static struct lm_list *
lmp_init (char *n)
{
struct lmp *lmp;
dbg("%s(\"%s\")", __func__, n);
lmp = xmalloc(sizeof(struct lmp));
lmp->p = n;
if (n[strlen(n)-1] == '/')
lmp->type = T_DIRECTORY;
else if (strchr(n,'/') == NULL)
lmp->type = T_BASENAME;
else
lmp->type = T_EXACT;
TAILQ_INIT(&lmp->lml);
TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link);
return (&lmp->lml);
}
/* libc basename is overkill. Return a pointer to the character after the
last /, or the original string if there are no slashes. */
static const char *
quickbasename (const char *path)
{
const char *p = path;
for (; *path; path++) {
if (*path == '/')
p = path+1;
}
return (p);
}
static int
readstrfn(void * cookie, char *buf, int len)
{
static char *current;
static int left;
int copied;
copied = 0;
if (!current) {
current = cookie;
left = strlen(cookie);
}
while (*current && left && len) {
*buf++ = *current++;
left--;
len--;
copied++;
}
return copied;
}
static int
closestrfn(void * cookie)
{
free(cookie);
return 0;
}

View File

@ -1,10 +0,0 @@
/*
* $FreeBSD: src/libexec/rtld-elf/libmap.h,v 1.4.20.1 2009/04/15 03:14:26 kensmith Exp $
*/
int lm_init (char *);
void lm_fini (void);
char * lm_find (const char *, const char *);
#ifdef COMPAT_32BIT
char * lm_findn (const char *, const char *, const int);
#endif

View File

@ -1,518 +0,0 @@
/*-
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)malloc.c 5.11 (Berkeley) 2/23/91";*/
static char *rcsid = "$FreeBSD: src/libexec/rtld-elf/malloc.c,v 1.11.8.1 2009/04/15 03:14:26 kensmith Exp $";
#endif /* LIBC_SCCS and not lint */
/*
* malloc.c (Caltech) 2/21/82
* Chris Kingsley, kingsley@cit-20.
*
* This is a very fast storage allocator. It allocates blocks of a small
* number of different sizes, and keeps free lists of each size. Blocks that
* don't exactly fit are passed up to the next larger size. In this
* implementation, the available sizes are 2^n-4 (or 2^n-10) bytes long.
* This is designed for use in a virtual memory environment.
*/
#include <sys/types.h>
#include <err.h>
#include <paths.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/mman.h>
#ifndef BSD
#define MAP_COPY MAP_PRIVATE
#define MAP_FILE 0
//#define MAP_ANON 0
#endif
#ifndef BSD /* Need do better than this */
#define NEED_DEV_ZERO 1
#endif
static void morecore();
static int findbucket();
/*
* Pre-allocate mmap'ed pages
*/
#define NPOOLPAGES (32*1024/pagesz)
static caddr_t pagepool_start, pagepool_end;
static int morepages();
/*
* The overhead on a block is at least 4 bytes. When free, this space
* contains a pointer to the next free block, and the bottom two bits must
* be zero. When in use, the first byte is set to MAGIC, and the second
* byte is the size index. The remaining bytes are for alignment.
* If range checking is enabled then a second word holds the size of the
* requested block, less 1, rounded up to a multiple of sizeof(RMAGIC).
* The order of elements is critical: ov_magic must overlay the low order
* bits of ov_next, and ov_magic can not be a valid ov_next bit pattern.
*/
union overhead {
union overhead *ov_next; /* when free */
struct {
u_char ovu_magic; /* magic number */
u_char ovu_index; /* bucket # */
#ifdef RCHECK
u_short ovu_rmagic; /* range magic number */
u_int ovu_size; /* actual block size */
#endif
} ovu;
#define ov_magic ovu.ovu_magic
#define ov_index ovu.ovu_index
#define ov_rmagic ovu.ovu_rmagic
#define ov_size ovu.ovu_size
};
#define MAGIC 0xef /* magic # on accounting info */
#define RMAGIC 0x5555 /* magic # on range info */
#ifdef RCHECK
#define RSLOP sizeof (u_short)
#else
#define RSLOP 0
#endif
/*
* nextf[i] is the pointer to the next free block of size 2^(i+3). The
* smallest allocatable block is 8 bytes. The overhead information
* precedes the data area returned to the user.
*/
#define NBUCKETS 30
static union overhead *nextf[NBUCKETS];
static int pagesz; /* page size */
static int pagebucket; /* page size bucket */
#ifdef MSTATS
/*
* nmalloc[i] is the difference between the number of mallocs and frees
* for a given block size.
*/
static u_int nmalloc[NBUCKETS];
#include <stdio.h>
#endif
#if defined(MALLOC_DEBUG) || defined(RCHECK)
#define ASSERT(p) if (!(p)) botch("p")
#include <stdio.h>
static void
botch(s)
char *s;
{
fprintf(stderr, "\r\nassertion botched: %s\r\n", s);
(void) fflush(stderr); /* just in case user buffered it */
abort();
}
#else
#define ASSERT(p)
#endif
/* Debugging stuff */
static void xprintf(const char *, ...);
#define TRACE() xprintf("TRACE %s:%d\n", __FILE__, __LINE__)
void *
malloc(nbytes)
size_t nbytes;
{
register union overhead *op;
register int bucket;
register long n;
register unsigned amt;
/*
* First time malloc is called, setup page size and
* align break pointer so all data will be page aligned.
*/
if (pagesz == 0) {
pagesz = n = getpagesize();
if (morepages(NPOOLPAGES) == 0)
return NULL;
op = (union overhead *)(pagepool_start);
n = n - sizeof (*op) - ((long)op & (n - 1));
if (n < 0)
n += pagesz;
if (n) {
pagepool_start += n;
}
bucket = 0;
amt = 8;
while ((unsigned)pagesz > amt) {
amt <<= 1;
bucket++;
}
pagebucket = bucket;
}
/*
* Convert amount of memory requested into closest block size
* stored in hash buckets which satisfies request.
* Account for space used per block for accounting.
*/
if (nbytes <= (unsigned long)(n = pagesz - sizeof (*op) - RSLOP)) {
#ifndef RCHECK
amt = 8; /* size of first bucket */
bucket = 0;
#else
amt = 16; /* size of first bucket */
bucket = 1;
#endif
n = -(sizeof (*op) + RSLOP);
} else {
amt = pagesz;
bucket = pagebucket;
}
while (nbytes > amt + n) {
amt <<= 1;
if (amt == 0)
return (NULL);
bucket++;
}
/*
* If nothing in hash bucket right now,
* request more memory from the system.
*/
if ((op = nextf[bucket]) == NULL) {
morecore(bucket);
if ((op = nextf[bucket]) == NULL)
return (NULL);
}
/* remove from linked list */
nextf[bucket] = op->ov_next;
op->ov_magic = MAGIC;
op->ov_index = bucket;
#ifdef MSTATS
nmalloc[bucket]++;
#endif
#ifdef RCHECK
/*
* Record allocated size of block and
* bound space with magic numbers.
*/
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
op->ov_rmagic = RMAGIC;
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
return ((char *)(op + 1));
}
void *
calloc(size_t num, size_t size)
{
void *ret;
if (size != 0 && (num * size) / size != num) {
/* size_t overflow. */
return (NULL);
}
if ((ret = malloc(num * size)) != NULL)
memset(ret, 0, num * size);
return (ret);
}
/*
* Allocate more memory to the indicated bucket.
*/
static void
morecore(bucket)
int bucket;
{
register union overhead *op;
register int sz; /* size of desired block */
int amt; /* amount to allocate */
int nblks; /* how many blocks we get */
/*
* sbrk_size <= 0 only for big, FLUFFY, requests (about
* 2^30 bytes on a VAX, I think) or for a negative arg.
*/
sz = 1 << (bucket + 3);
#ifdef MALLOC_DEBUG
ASSERT(sz > 0);
#else
if (sz <= 0)
return;
#endif
if (sz < pagesz) {
amt = pagesz;
nblks = amt / sz;
} else {
amt = sz + pagesz;
nblks = 1;
}
if (amt > pagepool_end - pagepool_start)
if (morepages(amt/pagesz + NPOOLPAGES) == 0)
return;
op = (union overhead *)pagepool_start;
pagepool_start += amt;
/*
* Add new memory allocated to that on
* free list for this hash bucket.
*/
nextf[bucket] = op;
while (--nblks > 0) {
op->ov_next = (union overhead *)((caddr_t)op + sz);
op = (union overhead *)((caddr_t)op + sz);
}
}
void
free(cp)
void *cp;
{
register int size;
register union overhead *op;
if (cp == NULL)
return;
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
#ifdef MALLOC_DEBUG
ASSERT(op->ov_magic == MAGIC); /* make sure it was in use */
#else
if (op->ov_magic != MAGIC)
return; /* sanity */
#endif
#ifdef RCHECK
ASSERT(op->ov_rmagic == RMAGIC);
ASSERT(*(u_short *)((caddr_t)(op + 1) + op->ov_size) == RMAGIC);
#endif
size = op->ov_index;
ASSERT(size < NBUCKETS);
op->ov_next = nextf[size]; /* also clobbers ov_magic */
nextf[size] = op;
#ifdef MSTATS
nmalloc[size]--;
#endif
}
/*
* When a program attempts "storage compaction" as mentioned in the
* old malloc man page, it realloc's an already freed block. Usually
* this is the last block it freed; occasionally it might be farther
* back. We have to search all the free lists for the block in order
* to determine its bucket: 1st we make one pass thru the lists
* checking only the first block in each; if that fails we search
* ``realloc_srchlen'' blocks in each list for a match (the variable
* is extern so the caller can modify it). If that fails we just copy
* however many bytes was given to realloc() and hope it's not huge.
*/
int realloc_srchlen = 4; /* 4 should be plenty, -1 =>'s whole list */
void *
realloc(cp, nbytes)
void *cp;
size_t nbytes;
{
register u_int onb;
register int i;
union overhead *op;
char *res;
int was_alloced = 0;
if (cp == NULL)
return (malloc(nbytes));
op = (union overhead *)((caddr_t)cp - sizeof (union overhead));
if (op->ov_magic == MAGIC) {
was_alloced++;
i = op->ov_index;
} else {
/*
* Already free, doing "compaction".
*
* Search for the old block of memory on the
* free list. First, check the most common
* case (last element free'd), then (this failing)
* the last ``realloc_srchlen'' items free'd.
* If all lookups fail, then assume the size of
* the memory block being realloc'd is the
* largest possible (so that all "nbytes" of new
* memory are copied into). Note that this could cause
* a memory fault if the old area was tiny, and the moon
* is gibbous. However, that is very unlikely.
*/
if ((i = findbucket(op, 1)) < 0 &&
(i = findbucket(op, realloc_srchlen)) < 0)
i = NBUCKETS;
}
onb = 1 << (i + 3);
if (onb < (u_int)pagesz)
onb -= sizeof (*op) + RSLOP;
else
onb += pagesz - sizeof (*op) - RSLOP;
/* avoid the copy if same size block */
if (was_alloced) {
if (i) {
i = 1 << (i + 2);
if (i < pagesz)
i -= sizeof (*op) + RSLOP;
else
i += pagesz - sizeof (*op) - RSLOP;
}
if (nbytes <= onb && nbytes > (size_t)i) {
#ifdef RCHECK
op->ov_size = (nbytes + RSLOP - 1) & ~(RSLOP - 1);
*(u_short *)((caddr_t)(op + 1) + op->ov_size) = RMAGIC;
#endif
return(cp);
} else
free(cp);
}
if ((res = malloc(nbytes)) == NULL)
return (NULL);
if (cp != res) /* common optimization if "compacting" */
bcopy(cp, res, (nbytes < onb) ? nbytes : onb);
return (res);
}
/*
* Search ``srchlen'' elements of each free list for a block whose
* header starts at ``freep''. If srchlen is -1 search the whole list.
* Return bucket number, or -1 if not found.
*/
static int
findbucket(freep, srchlen)
union overhead *freep;
int srchlen;
{
register union overhead *p;
register int i, j;
for (i = 0; i < NBUCKETS; i++) {
j = 0;
for (p = nextf[i]; p && j != srchlen; p = p->ov_next) {
if (p == freep)
return (i);
j++;
}
}
return (-1);
}
#ifdef MSTATS
/*
* mstats - print out statistics about malloc
*
* Prints two lines of numbers, one showing the length of the free list
* for each size category, the second showing the number of mallocs -
* frees for each size category.
*/
mstats(s)
char *s;
{
register int i, j;
register union overhead *p;
int totfree = 0,
totused = 0;
fprintf(stderr, "Memory allocation statistics %s\nfree:\t", s);
for (i = 0; i < NBUCKETS; i++) {
for (j = 0, p = nextf[i]; p; p = p->ov_next, j++)
;
fprintf(stderr, " %d", j);
totfree += j * (1 << (i + 3));
}
fprintf(stderr, "\nused:\t");
for (i = 0; i < NBUCKETS; i++) {
fprintf(stderr, " %d", nmalloc[i]);
totused += nmalloc[i] * (1 << (i + 3));
}
fprintf(stderr, "\n\tTotal in use: %d, total free: %d\n",
totused, totfree);
}
#endif
static int
morepages(n)
int n;
{
int fd = -1;
int offset;
#ifdef NEED_DEV_ZERO
fd = open(_PATH_DEVZERO, O_RDWR, 0);
if (fd == -1)
perror(_PATH_DEVZERO);
#endif
if (pagepool_end - pagepool_start > pagesz) {
caddr_t addr = (caddr_t)
(((long)pagepool_start + pagesz - 1) & ~(pagesz - 1));
if (munmap(addr, pagepool_end - addr) != 0)
warn("morepages: munmap %p", addr);
}
offset = (long)pagepool_start - ((long)pagepool_start & ~(pagesz - 1));
if ((pagepool_start = mmap(0, n * pagesz,
PROT_READ|PROT_WRITE,
MAP_ANON|MAP_COPY, fd, 0)) == (caddr_t)-1) {
xprintf("Cannot map anonymous memory");
return 0;
}
pagepool_end = pagepool_start + n * pagesz;
pagepool_start += offset;
#ifdef NEED_DEV_ZERO
close(fd);
#endif
return n;
}
/*
* Non-mallocing printf, for use by malloc itself.
*/
static void
xprintf(const char *fmt, ...)
{
char buf[256];
va_list ap;
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
(void)write(STDOUT_FILENO, buf, strlen(buf));
va_end(ap);
}

View File

@ -1,283 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/map_object.c,v 1.18.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
#include <sys/param.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <errno.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#include "file.h"
#include "rtld.h"
static Elf_Ehdr *get_elf_header (int, const char *);
/*
* Map a shared object into memory. The "fd" argument is a file descriptor,
* which must be open on the object and positioned at its beginning.
* The "path" argument is a pathname that is used only for error messages.
*
* The return value is a pointer to a newly-allocated Obj_Entry structure
* for the shared object. Returns NULL on failure.
*/
Obj_Entry *
map_object(int fd, const char *path, const struct stat *sb)
{
Obj_Entry *obj;
Elf_Ehdr *hdr;
Elf_Phdr *phdr;
Elf_Phdr *phlimit;
Elf_Phdr **segs;
int nsegs;
Elf_Phdr *phdyn;
Elf_Phdr *phinterp;
Elf_Phdr *phtls;
caddr_t mapbase;
size_t mapsize;
Elf_Addr base_vaddr;
Elf_Addr base_vlimit;
size_t phsize;
hdr = get_elf_header(fd, path);
if (hdr == NULL)
return (NULL);
/*
* Scan the program header entries, and save key information.
*
* We rely on there being exactly two load segments, text and data,
* in that order.
*/
phdr = (Elf_Phdr *) ((char *)hdr + hdr->e_phoff);
phsize = hdr->e_phnum * sizeof (phdr[0]);
phlimit = phdr + hdr->e_phnum;
nsegs = -1;
phdyn = phinterp = phtls = NULL;
segs = alloca(sizeof(segs[0]) * hdr->e_phnum);
while (phdr < phlimit) {
switch (phdr->p_type) {
case PT_INTERP:
phinterp = phdr;
break;
case PT_LOAD:
segs[++nsegs] = phdr;
if ((segs[nsegs]->p_align & (PAGE_SIZE - 1)) != 0) {
_rtld_error("%s: PT_LOAD segment %d not page-aligned",
path, nsegs);
return NULL;
}
break;
case PT_PHDR:
phsize = phdr->p_memsz;
break;
case PT_DYNAMIC:
phdyn = phdr;
break;
case PT_TLS:
phtls = phdr;
break;
}
++phdr;
}
if (phdyn == NULL) {
_rtld_error("%s: object is not dynamically-linked", path);
return NULL;
}
if (nsegs < 0) {
_rtld_error("%s: too few PT_LOAD segments", path);
return NULL;
}
/*
* Map the entire address space of the object, to stake out our
* contiguous region, and to establish the base address for relocation.
*/
base_vaddr = trunc_page(segs[0]->p_vaddr);
base_vlimit = round_page(segs[nsegs]->p_vaddr + segs[nsegs]->p_memsz);
mapsize = base_vlimit - base_vaddr;
mapbase = genode_map(fd, segs);
obj = obj_new();
if (sb != NULL) {
obj->dev = sb->st_dev;
obj->ino = sb->st_ino;
}
obj->mapbase = mapbase;
obj->mapsize = mapsize;
obj->textsize = round_page(segs[0]->p_vaddr + segs[0]->p_memsz) -
base_vaddr;
obj->vaddrbase = base_vaddr;
obj->relocbase = mapbase - base_vaddr;
obj->dynamic = (const Elf_Dyn *) (obj->relocbase + phdyn->p_vaddr);
if (hdr->e_entry != 0)
obj->entry = (caddr_t) (obj->relocbase + hdr->e_entry);
/* cbass: copy program header */
obj->phdr = malloc(phsize);
if (obj->phdr == NULL) {
obj_free(obj);
_rtld_error("%s: cannot allocate program header", path);
return NULL;
}
memcpy((char *)obj->phdr, (char *)hdr + hdr->e_phoff, phsize);
obj->phdr_alloc = true;
obj->phsize = phsize;
if (phinterp != NULL)
obj->interp = (const char *) (obj->relocbase + phinterp->p_vaddr);
if (phtls != NULL) {
tls_dtv_generation++;
obj->tlsindex = ++tls_max_index;
obj->tlssize = phtls->p_memsz;
obj->tlsalign = phtls->p_align;
obj->tlsinitsize = phtls->p_filesz;
obj->tlsinit = mapbase + phtls->p_vaddr;
}
return obj;
}
static Elf_Ehdr *
get_elf_header (int fd, const char *path)
{
static union {
Elf_Ehdr hdr;
char buf[PAGE_SIZE];
} u;
ssize_t nbytes;
if ((nbytes = read(fd, u.buf, PAGE_SIZE)) == -1) {
_rtld_error("%s: read error: %s", path, strerror(errno));
return NULL;
}
/* Make sure the file is valid */
if (nbytes < (ssize_t)sizeof(Elf_Ehdr) || !IS_ELF(u.hdr)) {
_rtld_error("%s: invalid file format", path);
return NULL;
}
if (u.hdr.e_ident[EI_CLASS] != ELF_TARG_CLASS
|| u.hdr.e_ident[EI_DATA] != ELF_TARG_DATA) {
_rtld_error("%s: unsupported file layout", path);
return NULL;
}
if (u.hdr.e_ident[EI_VERSION] != EV_CURRENT
|| u.hdr.e_version != EV_CURRENT) {
_rtld_error("%s: unsupported file version", path);
return NULL;
}
if (u.hdr.e_type != ET_EXEC && u.hdr.e_type != ET_DYN) {
_rtld_error("%s: unsupported file type", path);
return NULL;
}
if (u.hdr.e_machine != ELF_TARG_MACH) {
_rtld_error("%s: unsupported machine", path);
return NULL;
}
/*
* We rely on the program header being in the first page. This is
* not strictly required by the ABI specification, but it seems to
* always true in practice. And, it simplifies things considerably.
*/
if (u.hdr.e_phentsize != sizeof(Elf_Phdr)) {
_rtld_error(
"%s: invalid shared object: e_phentsize != sizeof(Elf_Phdr)", path);
return NULL;
}
if (u.hdr.e_phoff + u.hdr.e_phnum * sizeof(Elf_Phdr) > (size_t)nbytes) {
_rtld_error("%s: program header too large", path);
return NULL;
}
return (&u.hdr);
}
void
obj_free(Obj_Entry *obj)
{
Objlist_Entry *elm;
if (obj->tls_done)
free_tls_offset(obj);
while (obj->needed != NULL) {
Needed_Entry *needed = obj->needed;
obj->needed = needed->next;
free(needed);
}
while (!STAILQ_EMPTY(&obj->names)) {
Name_Entry *entry = STAILQ_FIRST(&obj->names);
STAILQ_REMOVE_HEAD(&obj->names, link);
free(entry);
}
while (!STAILQ_EMPTY(&obj->dldags)) {
elm = STAILQ_FIRST(&obj->dldags);
STAILQ_REMOVE_HEAD(&obj->dldags, link);
free(elm);
}
while (!STAILQ_EMPTY(&obj->dagmembers)) {
elm = STAILQ_FIRST(&obj->dagmembers);
STAILQ_REMOVE_HEAD(&obj->dagmembers, link);
free(elm);
}
if (obj->vertab)
free(obj->vertab);
if (obj->origin_path)
free(obj->origin_path);
if (obj->priv)
free(obj->priv);
if (obj->path)
free(obj->path);
if (obj->phdr_alloc)
free((void *)obj->phdr);
free(obj);
}
Obj_Entry *
obj_new(void)
{
Obj_Entry *obj;
obj = CNEW(Obj_Entry);
STAILQ_INIT(&obj->dldags);
STAILQ_INIT(&obj->dagmembers);
STAILQ_INIT(&obj->names);
return obj;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +0,0 @@
/*-
* Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/rtld.h,v 1.38.8.1 2009/04/15 03:14:26 kensmith Exp $
*/
#ifndef RTLD_H /* { */
#define RTLD_H 1
#include <machine/elf.h>
#include <sys/types.h>
#include <sys/queue.h>
#include <elf-hints.h>
#include <link.h>
#include <stddef.h>
#include "rtld_lock.h"
#include "rtld_machdep.h"
#ifdef COMPAT_32BIT
#undef STANDARD_LIBRARY_PATH
#undef _PATH_ELF_HINTS
#define _PATH_ELF_HINTS "/var/run/ld-elf32.so.hints"
/* For running 32 bit binaries */
#define STANDARD_LIBRARY_PATH "/lib32:/usr/lib32"
#define LD_ "LD_32_"
#endif
#ifndef STANDARD_LIBRARY_PATH
#define STANDARD_LIBRARY_PATH "/lib:/usr/lib"
#endif
#ifndef LD_
#define LD_ "LD_"
#endif
#define NEW(type) ((type *) xmalloc(sizeof(type)))
#define CNEW(type) ((type *) xcalloc(sizeof(type)))
/* We might as well do booleans like C++. */
typedef unsigned char bool;
#define false 0
#define true 1
extern size_t tls_last_offset;
extern size_t tls_last_size;
extern size_t tls_static_space;
extern int tls_dtv_generation;
extern int tls_max_index;
struct stat;
struct Struct_Obj_Entry;
/* Lists of shared objects */
typedef struct Struct_Objlist_Entry {
STAILQ_ENTRY(Struct_Objlist_Entry) link;
struct Struct_Obj_Entry *obj;
} Objlist_Entry;
typedef STAILQ_HEAD(Struct_Objlist, Struct_Objlist_Entry) Objlist;
/* Types of init and fini functions */
typedef void (*InitFunc)(void);
/* Lists of shared object dependencies */
typedef struct Struct_Needed_Entry {
struct Struct_Needed_Entry *next;
struct Struct_Obj_Entry *obj;
unsigned long name; /* Offset of name in string table */
} Needed_Entry;
typedef struct Struct_Name_Entry {
STAILQ_ENTRY(Struct_Name_Entry) link;
char name[1];
} Name_Entry;
/* Lock object */
typedef struct Struct_LockInfo {
void *context; /* Client context for creating locks */
void *thelock; /* The one big lock */
/* Debugging aids. */
volatile int rcount; /* Number of readers holding lock */
volatile int wcount; /* Number of writers holding lock */
/* Methods */
void *(*lock_create)(void *context);
void (*rlock_acquire)(void *lock);
void (*wlock_acquire)(void *lock);
void (*rlock_release)(void *lock);
void (*wlock_release)(void *lock);
void (*lock_destroy)(void *lock);
void (*context_destroy)(void *context);
} LockInfo;
typedef struct Struct_Ver_Entry {
Elf_Word hash;
unsigned int flags;
const char *name;
const char *file;
} Ver_Entry;
#define VER_INFO_HIDDEN 0x01
/*
* Shared object descriptor.
*
* Items marked with "(%)" are dynamically allocated, and must be freed
* when the structure is destroyed.
*
* CAUTION: It appears that the JDK port peeks into these structures.
* It looks at "next" and "mapbase" at least. Don't add new members
* near the front, until this can be straightened out.
*/
typedef struct Struct_Obj_Entry {
/*
* These two items have to be set right for compatibility with the
* original ElfKit crt1.o.
*/
Elf_Size magic; /* Magic number (sanity check) */
Elf_Size version; /* Version number of struct format */
struct Struct_Obj_Entry *next;
char *path; /* Pathname of underlying file (%) */
char *origin_path; /* Directory path of origin file */
int refcount;
int dl_refcount; /* Number of times loaded by dlopen */
/* These items are computed by map_object() or by digest_phdr(). */
caddr_t mapbase; /* Base address of mapped region */
size_t mapsize; /* Size of mapped region in bytes */
size_t textsize; /* Size of text segment in bytes */
Elf_Addr vaddrbase; /* Base address in shared object file */
caddr_t relocbase; /* Relocation constant = mapbase - vaddrbase */
const Elf_Dyn *dynamic; /* Dynamic section */
caddr_t entry; /* Entry point */
const Elf_Phdr *phdr; /* Program header if it is mapped, else NULL */
size_t phsize; /* Size of program header in bytes */
const char *interp; /* Pathname of the interpreter, if any */
/* TLS information */
int tlsindex; /* Index in DTV for this module */
void *tlsinit; /* Base address of TLS init block */
size_t tlsinitsize; /* Size of TLS init block for this module */
size_t tlssize; /* Size of TLS block for this module */
size_t tlsoffset; /* Offset of static TLS block for this module */
size_t tlsalign; /* Alignment of static TLS block */
/* Items from the dynamic section. */
Elf_Addr *pltgot; /* PLT or GOT, depending on architecture */
const Elf_Rel *rel; /* Relocation entries */
unsigned long relsize; /* Size in bytes of relocation info */
const Elf_Rela *rela; /* Relocation entries with addend */
unsigned long relasize; /* Size in bytes of addend relocation info */
const Elf_Rel *pltrel; /* PLT relocation entries */
unsigned long pltrelsize; /* Size in bytes of PLT relocation info */
const Elf_Rela *pltrela; /* PLT relocation entries with addend */
unsigned long pltrelasize; /* Size in bytes of PLT addend reloc info */
const Elf_Sym *symtab; /* Symbol table */
const char *strtab; /* String table */
unsigned long strsize; /* Size in bytes of string table */
const Elf_Verneed *verneed; /* Required versions. */
Elf_Word verneednum; /* Number of entries in verneed table */
const Elf_Verdef *verdef; /* Provided versions. */
Elf_Word verdefnum; /* Number of entries in verdef table */
const Elf_Versym *versyms; /* Symbol versions table */
const Elf_Hashelt *buckets; /* Hash table buckets array */
unsigned long nbuckets; /* Number of buckets */
const Elf_Hashelt *chains; /* Hash table chain array */
unsigned long nchains; /* Number of chains */
const char *rpath; /* Search path specified in object */
Needed_Entry *needed; /* Shared objects needed by this one (%) */
STAILQ_HEAD(, Struct_Name_Entry) names; /* List of names for this object we
know about. */
Ver_Entry *vertab; /* Versions required /defined by this object */
int vernum; /* Number of entries in vertab */
Elf_Addr init; /* Initialization function to call */
Elf_Addr fini; /* Termination function to call */
bool mainprog : 1; /* True if this is the main program */
bool rtld : 1; /* True if this is the dynamic linker */
bool rtld_init : 1; /* True during rtld initialization */
bool textrel : 1; /* True if there are relocations to text seg */
bool symbolic : 1; /* True if generated with "-Bsymbolic" */
bool bind_now : 1; /* True if all relocations should be made first */
bool traced : 1; /* Already printed in ldd trace output */
bool jmpslots_done : 1; /* Already have relocated the jump slots */
bool init_done : 1; /* Already have added object to init list */
bool tls_done : 1; /* Already allocated offset for static TLS */
bool phdr_alloc : 1; /* Phdr is allocated and needs to be freed. */
struct link_map linkmap; /* for GDB and dlinfo() */
Objlist dldags; /* Object belongs to these dlopened DAGs (%) */
Objlist dagmembers; /* DAG has these members (%) */
dev_t dev; /* Object's filesystem's device */
ino_t ino; /* Object's inode number */
void *priv; /* Platform-dependant */
} Obj_Entry;
#define RTLD_MAGIC 0xd550b87a
#define RTLD_VERSION 1
#define RTLD_STATIC_TLS_EXTRA 64
/* Flags to be passed into symlook_ family of functions. */
#define SYMLOOK_IN_PLT 0x01 /* Lookup for PLT symbol */
#define SYMLOOK_DLSYM 0x02 /* Return newes versioned symbol. Used by
dlsym. */
/*
* Symbol cache entry used during relocation to avoid multiple lookups
* of the same symbol.
*/
typedef struct Struct_SymCache {
const Elf_Sym *sym; /* Symbol table entry */
const Obj_Entry *obj; /* Shared object which defines it */
} SymCache;
extern void _rtld_error(const char *, ...) __printflike(1, 2);
extern Obj_Entry *map_object(int, const char *, const struct stat *);
extern void *xcalloc(size_t);
extern void *xmalloc(size_t);
extern char *xstrdup(const char *);
extern Elf_Addr _GLOBAL_OFFSET_TABLE_[];
extern void dump_relocations (Obj_Entry *);
extern void dump_obj_relocations (Obj_Entry *);
extern void dump_Elf_Rel (Obj_Entry *, const Elf_Rel *, u_long);
extern void dump_Elf_Rela (Obj_Entry *, const Elf_Rela *, u_long);
/*
* Function declarations.
*/
unsigned long elf_hash(const char *);
const Elf_Sym *find_symdef(unsigned long, const Obj_Entry *,
const Obj_Entry **, int, SymCache *);
void init_pltgot(Obj_Entry *);
void lockdflt_init(void);
void obj_free(Obj_Entry *);
Obj_Entry *obj_new(void);
void _rtld_bind_start(void);
const Elf_Sym *symlook_obj(const char *, unsigned long, const Obj_Entry *,
const Ver_Entry *, int);
void *tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset);
void *allocate_tls(Obj_Entry *, void *, size_t, size_t);
void free_tls(void *, size_t, size_t);
void *allocate_module_tls(int index);
bool allocate_tls_offset(Obj_Entry *obj);
void free_tls_offset(Obj_Entry *obj);
const Ver_Entry *fetch_ventry(const Obj_Entry *obj, unsigned long);
void set_program_var(const char *name, const void *value);
/*
* MD function declarations.
*/
int do_copy_relocations(Obj_Entry *);
int reloc_non_plt(Obj_Entry *, Obj_Entry *);
int reloc_plt(Obj_Entry *);
int reloc_jmpslots(Obj_Entry *);
void allocate_initial_tls(Obj_Entry *);
#endif /* } */

View File

@ -1,334 +0,0 @@
/*-
* Copyright 1999, 2000 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* from: FreeBSD: src/libexec/rtld-elf/sparc64/lockdflt.c,v 1.3 2002/10/09
* $FreeBSD: src/libexec/rtld-elf/rtld_lock.c,v 1.4.2.3.2.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Thread locking implementation for the dynamic linker.
*
* We use the "simple, non-scalable reader-preference lock" from:
*
* J. M. Mellor-Crummey and M. L. Scott. "Scalable Reader-Writer
* Synchronization for Shared-Memory Multiprocessors." 3rd ACM Symp. on
* Principles and Practice of Parallel Programming, April 1991.
*
* In this algorithm the lock is a single word. Its low-order bit is
* set when a writer holds the lock. The remaining high-order bits
* contain a count of readers desiring the lock. The algorithm requires
* atomic "compare_and_store" and "add" operations, which we implement
* using assembly language sequences in "rtld_start.S".
*/
#include <signal.h>
#include <stdlib.h>
#include <time.h>
#include "debug.h"
#include "rtld.h"
#include "rtld_machdep.h"
#define WAFLAG 0x1 /* A writer holds the lock */
#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */
typedef struct Struct_Lock {
volatile u_int lock;
void *base;
} Lock;
static sigset_t fullsigmask, oldsigmask;
static int thread_flag;
static void *
def_lock_create()
{
void *base;
char *p;
uintptr_t r;
Lock *l;
/*
* Arrange for the lock to occupy its own cache line. First, we
* optimistically allocate just a cache line, hoping that malloc
* will give us a well-aligned block of memory. If that doesn't
* work, we allocate a larger block and take a well-aligned cache
* line from it.
*/
base = xmalloc(CACHE_LINE_SIZE);
p = (char *)base;
if ((uintptr_t)p % CACHE_LINE_SIZE != 0) {
free(base);
base = xmalloc(2 * CACHE_LINE_SIZE);
p = (char *)base;
if ((r = (uintptr_t)p % CACHE_LINE_SIZE) != 0)
p += CACHE_LINE_SIZE - r;
}
l = (Lock *)p;
l->base = base;
l->lock = 0;
return l;
}
static void
def_lock_destroy(void *lock)
{
Lock *l = (Lock *)lock;
free(l->base);
}
static void
def_rlock_acquire(void *lock)
{
Lock *l = (Lock *)lock;
atomic_add_acq_int(&l->lock, RC_INCR);
while (l->lock & WAFLAG)
; /* Spin */
}
static void
def_wlock_acquire(void *lock)
{
Lock *l = (Lock *)lock;
sigset_t tmp_oldsigmask;
for ( ; ; ) {
sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
if (atomic_cmpset_acq_int(&l->lock, 0, WAFLAG))
break;
sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
}
oldsigmask = tmp_oldsigmask;
}
static void
def_lock_release(void *lock)
{
Lock *l = (Lock *)lock;
if ((l->lock & WAFLAG) == 0)
atomic_add_rel_int(&l->lock, -RC_INCR);
else {
atomic_add_rel_int(&l->lock, -WAFLAG);
sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
}
}
static int
def_thread_set_flag(int mask)
{
int old_val = thread_flag;
thread_flag |= mask;
return (old_val);
}
static int
def_thread_clr_flag(int mask)
{
int old_val = thread_flag;
thread_flag &= ~mask;
return (old_val);
}
/*
* Public interface exposed to the rest of the dynamic linker.
*/
static struct RtldLockInfo lockinfo;
static struct RtldLockInfo deflockinfo;
static __inline int
thread_mask_set(int mask)
{
return lockinfo.thread_set_flag(mask);
}
static __inline void
thread_mask_clear(int mask)
{
lockinfo.thread_clr_flag(mask);
}
#define RTLD_LOCK_CNT 3
struct rtld_lock {
void *handle;
int mask;
} rtld_locks[RTLD_LOCK_CNT];
rtld_lock_t rtld_bind_lock = &rtld_locks[0];
rtld_lock_t rtld_libc_lock = &rtld_locks[1];
rtld_lock_t rtld_phdr_lock = &rtld_locks[2];
int
rlock_acquire(rtld_lock_t lock)
{
if (thread_mask_set(lock->mask) & lock->mask) {
dbg("rlock_acquire: recursed");
return (0);
}
lockinfo.rlock_acquire(lock->handle);
return (1);
}
int
wlock_acquire(rtld_lock_t lock)
{
if (thread_mask_set(lock->mask) & lock->mask) {
dbg("wlock_acquire: recursed");
return (0);
}
lockinfo.wlock_acquire(lock->handle);
return (1);
}
void
rlock_release(rtld_lock_t lock, int locked)
{
if (locked == 0)
return;
thread_mask_clear(lock->mask);
lockinfo.lock_release(lock->handle);
}
void
wlock_release(rtld_lock_t lock, int locked)
{
if (locked == 0)
return;
thread_mask_clear(lock->mask);
lockinfo.lock_release(lock->handle);
}
void
lockdflt_init()
{
int i;
deflockinfo.rtli_version = RTLI_VERSION;
deflockinfo.lock_create = def_lock_create;
deflockinfo.lock_destroy = def_lock_destroy;
deflockinfo.rlock_acquire = def_rlock_acquire;
deflockinfo.wlock_acquire = def_wlock_acquire;
deflockinfo.lock_release = def_lock_release;
deflockinfo.thread_set_flag = def_thread_set_flag;
deflockinfo.thread_clr_flag = def_thread_clr_flag;
deflockinfo.at_fork = NULL;
for (i = 0; i < RTLD_LOCK_CNT; i++) {
rtld_locks[i].mask = (1 << i);
rtld_locks[i].handle = NULL;
}
memcpy(&lockinfo, &deflockinfo, sizeof(lockinfo));
_rtld_thread_init(NULL);
/*
* Construct a mask to block all signals except traps which might
* conceivably be generated within the dynamic linker itself.
*/
sigfillset(&fullsigmask);
sigdelset(&fullsigmask, SIGILL);
sigdelset(&fullsigmask, SIGTRAP);
sigdelset(&fullsigmask, SIGABRT);
sigdelset(&fullsigmask, SIGEMT);
sigdelset(&fullsigmask, SIGFPE);
sigdelset(&fullsigmask, SIGBUS);
sigdelset(&fullsigmask, SIGSEGV);
sigdelset(&fullsigmask, SIGSYS);
}
/*
* Callback function to allow threads implementation to
* register their own locking primitives if the default
* one is not suitable.
* The current context should be the only context
* executing at the invocation time.
*/
void
_rtld_thread_init(struct RtldLockInfo *pli)
{
int flags, i;
void *locks[RTLD_LOCK_CNT];
/* disable all locking while this function is running */
flags = thread_mask_set(~0);
if (pli == NULL)
pli = &deflockinfo;
for (i = 0; i < RTLD_LOCK_CNT; i++)
if ((locks[i] = pli->lock_create()) == NULL)
break;
if (i < RTLD_LOCK_CNT) {
while (--i >= 0)
pli->lock_destroy(locks[i]);
abort();
}
for (i = 0; i < RTLD_LOCK_CNT; i++) {
if (rtld_locks[i].handle == NULL)
continue;
if (flags & rtld_locks[i].mask)
lockinfo.lock_release(rtld_locks[i].handle);
lockinfo.lock_destroy(rtld_locks[i].handle);
}
for (i = 0; i < RTLD_LOCK_CNT; i++) {
rtld_locks[i].handle = locks[i];
if (flags & rtld_locks[i].mask)
pli->wlock_acquire(rtld_locks[i].handle);
}
lockinfo.lock_create = pli->lock_create;
lockinfo.lock_destroy = pli->lock_destroy;
lockinfo.rlock_acquire = pli->rlock_acquire;
lockinfo.wlock_acquire = pli->wlock_acquire;
lockinfo.lock_release = pli->lock_release;
lockinfo.thread_set_flag = pli->thread_set_flag;
lockinfo.thread_clr_flag = pli->thread_clr_flag;
lockinfo.at_fork = pli->at_fork;
/* restore thread locking state, this time with new locks */
thread_mask_clear(~0);
thread_mask_set(flags);
dbg("_rtld_thread_init: done");
}
void
_rtld_atfork_pre(int *locks)
{
locks[2] = wlock_acquire(rtld_phdr_lock);
locks[0] = rlock_acquire(rtld_bind_lock);
}
void
_rtld_atfork_post(int *locks)
{
rlock_release(rtld_bind_lock, locks[0]);
wlock_release(rtld_phdr_lock, locks[2]);
}

View File

@ -1,73 +0,0 @@
/*-
* Copyright 2003 Alexander Kabaev.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/rtld_lock.h,v 1.2.20.2.2.1 2009/04/15 03:14:26 kensmith Exp $
*/
#ifndef _RTLD_LOCK_H_
#define _RTLD_LOCK_H_
#define RTLI_VERSION 0x01
#define MAX_RTLD_LOCKS 8
struct RtldLockInfo
{
unsigned int rtli_version;
void *(*lock_create)(void);
void (*lock_destroy)(void *);
void (*rlock_acquire)(void *);
void (*wlock_acquire)(void *);
void (*lock_release)(void *);
int (*thread_set_flag)(int);
int (*thread_clr_flag)(int);
void (*at_fork)(void);
};
extern void _rtld_thread_init(struct RtldLockInfo *);
extern void _rtld_atfork_pre(int *);
extern void _rtld_atfork_post(int *);
#ifdef IN_RTLD
struct rtld_lock;
typedef struct rtld_lock *rtld_lock_t;
extern rtld_lock_t rtld_bind_lock;
extern rtld_lock_t rtld_libc_lock;
extern rtld_lock_t rtld_phdr_lock;
#ifdef __cplusplus
extern "C" {
#endif
int rlock_acquire(rtld_lock_t);
int wlock_acquire(rtld_lock_t);
void rlock_release(rtld_lock_t, int);
void wlock_release(rtld_lock_t, int);
#ifdef __cplusplus
}
#endif
#endif /* IN_RTLD */
#endif

View File

@ -1,69 +0,0 @@
/*-
* Copyright (c) 2004 Doug Rabson
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/libexec/rtld-elf/rtld_tls.h,v 1.1.28.1 2009/04/15 03:14:26 kensmith Exp $
*/
/*
* Semi-public interface from thread libraries to rtld for managing
* TLS.
*/
#ifndef _RTLD_TLS_H_
#define _RTLD_TLS_H_
/*
* Allocate a TLS block for a new thread. The memory allocated will
* include 'tcbsize' bytes aligned to a 'tcbalign' boundary (in bytes)
* for the thread library's private purposes. The location of the TCB
* block is returned by this function. For architectures using
* 'Variant I' TLS, the thread local storage follows the TCB, and for
* 'Variant II', the thread local storage precedes it. For
* architectures using the 'Variant II' model (e.g. i386, amd64,
* sparc64), the TCB must begin with two pointer fields which are used
* by rtld for its TLS implementation. For the 'Variant I' model, the
* TCB must begin with a single pointer field for rtld's
* implementation.
*
* If the value of 'oldtls' is non-NULL, the new TLS block will be
* initialised using the values contained in 'oldtls' and 'oldtls'
* will be freed. This is typically used when initialising a thread
* library to migrate from using the initial bootstrap TLS block
* created by rtld to one which contains suitable thread library
* private data.
*
* The value returned from this function is suitable for installing
* directly into the thread pointer register.
*/
extern void *_rtld_allocate_tls(void* oldtls, size_t tcbsize, size_t tcbalign);
/*
* Free a TLS block allocated using _rtld_allocate_tls(). The tcbsize
* and tcbalign parameters must be the same as those used to allocate
* the block.
*/
extern void _rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign);
#endif

View File

@ -1,59 +0,0 @@
/*-
* Copyright 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 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.
*
* $FreeBSD: src/libexec/rtld-elf/xmalloc.c,v 1.3.30.1 2009/04/15 03:14:26 kensmith Exp $
*/
#include <err.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
void *xcalloc(size_t);
void *xmalloc(size_t);
char *xstrdup(const char *);
void *
xcalloc(size_t size)
{
return memset(xmalloc(size), 0, size);
}
void *
xmalloc(size_t size)
{
void *p = malloc(size);
if (p == NULL)
err(1, "Out of memory");
return p;
}
char *
xstrdup(const char *s)
{
char *p = strdup(s);
if (p == NULL)
err(1, "Out of memory");
return p;
}

View File

@ -1,30 +0,0 @@
/*
* \brief Unoffical dlfnc.h extensions
* \author Sebastian.Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-07-05
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _DL_EXTENSIONS_
#define _DL_EXTENSIONS_
/* For a given PC, find the .so that it belongs to.
* Returns the base address of the .ARM.exidx section
* for that .so, and the number of 8-byte entries
* in that section (via *pcount).
* Intended to be called by libc's __gnu_Unwind_Find_exidx().
*
* 'Quoted from Android'
*/
#ifdef __ARM_EABI__
unsigned long dl_unwind_find_exidx(unsigned long pc, int *pcount);
#endif
#endif /* _DL_EXTENSIONS_ */

View File

@ -1,22 +0,0 @@
/*
* \brief Dummy 'lx_environ' used on on-Linux platforms
* \author Norman Feske
* \date 2011-08-23
*/
/*
* Copyright (C) 2011-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
/*
* The 'lx_environ' pointer is supposed to be initialized by the startup code
* on Linux. It is specially treated in 'main.c'. On platforms w/o 'lx_environ',
* we resolve the symbol by the weak symbol defined here. On Linux, the
* weak symbol is overridden by the version in the startup library.
*
* XXX: We should better remove the Linux-specific code from ldso's 'main.c'.
*/
__attribute__((weak)) char **lx_environ = (char **)0;

View File

@ -1,29 +0,0 @@
/*
* \brief Error message handling
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <err.h>
#include <base/env.h>
#include <base/printf.h>
extern "C" void errx(int eval, const char *fmt, ...)
{
using namespace Genode;
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
printf("\n");
env()->parent()->exit(eval);
while(1) ;
}

View File

@ -1,415 +0,0 @@
/*
* \brief libc file handling function emulation (open/read/write/mmap)
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <base/allocator_avl.h>
#include <base/printf.h>
#include <ldso/arch.h>
#include <rom_session/connection.h>
#include <rm_session/connection.h>
#include <sys/mman.h>
#include <sys/param.h>
#include <util/list.h>
#include <util/construct_at.h>
#include "file.h"
extern int debug;
namespace Genode {
/**
* Managed dataspace for ELF files (singelton)
*/
class Rm_area : public Rm_connection
{
private:
/* size of dataspace */
enum { RESERVATION = 160 * 1024 * 1024 };
addr_t _base; /* base address of dataspace */
Allocator_avl _range; /* VM range allocator */
protected:
Rm_area(addr_t base)
: Rm_connection(0, RESERVATION), _range(env()->heap())
{
on_destruction(KEEP_OPEN);
_base = (addr_t) env()->rm_session()->attach_at(dataspace(), base);
_range.add_range(base, RESERVATION);
}
public:
static Rm_area *r(addr_t base = 0)
{
/*
* The capabilities in this class become invalid when doing a
* fork in the noux environment. Hence avoid destruction of
* the singleton object as the destructor would try to access
* the capabilities also in the forked process.
*/
static bool constructed = 0;
static char placeholder[sizeof(Rm_area)];
if (!constructed) {
construct_at<Rm_area>(placeholder, base);
constructed = 1;
}
return reinterpret_cast<Rm_area *>(placeholder);
}
/**
* Reserve VM region of 'size' at 'vaddr'. Allocate any free region if
* 'vaddr' is zero
*/
addr_t alloc_region(size_t size, addr_t vaddr = 0)
{
addr_t addr = vaddr;
if (addr && (_range.alloc_addr(size, addr).is_error()))
throw Region_conflict();
else if (!addr && _range.alloc_aligned(size, (void **)&addr, 12).is_error())
throw Region_conflict();
return addr;
}
void free_region(addr_t vaddr) { _range.free((void *)vaddr); }
/**
* Overwritten from 'Rm_connection'
*/
Local_addr attach_at(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_at(ds, local_addr - _base, size, offset); }
/**
* Overwritten from 'Rm_connection'
*/
Local_addr attach_executable(Dataspace_capability ds, addr_t local_addr,
size_t size = 0, off_t offset = 0) {
return Rm_connection::attach_executable(ds, local_addr - _base, size, offset); }
void detach(Local_addr local_addr) {
Rm_connection::detach((addr_t)local_addr - _base); }
};
class Fd_handle : public List<Fd_handle>::Element
{
private:
addr_t _phdr;
addr_t _vaddr; /* image start */
addr_t _daddr; /* data start */
Rom_dataspace_capability _ds_rom; /* image ds */
Ram_dataspace_capability _ds_ram; /* data ds */
int _fd; /* file handle */
Session_capability _rom_cap;
public:
Fd_handle(int fd, Rom_dataspace_capability ds_rom, Session_capability rom_cap)
: _vaddr(~0UL), _ds_rom(ds_rom), _fd(fd), _rom_cap(rom_cap)
{
_phdr = (addr_t)env()->rm_session()->attach(_ds_rom, PAGE_SIZE);
}
addr_t vaddr() { return _vaddr; }
void vaddr(addr_t vaddr) { _vaddr = vaddr; }
Rom_dataspace_capability dataspace() { return _ds_rom; }
addr_t phdr() { return _phdr; }
void setup_data(addr_t vaddr, addr_t vlimit, addr_t flimit, off_t offset)
{
/* allocate data segment */
_ds_ram = env()->ram_session()->alloc(vlimit - vaddr);
Rm_area::r()->attach_at(_ds_ram, vaddr);
/* map rom data segment */
void *rom_data = env()->rm_session()->attach(_ds_rom, 0, offset);
/* copy data */
memcpy((void *)vaddr, rom_data, flimit - vaddr);
env()->rm_session()->detach(rom_data);
/* set parent cap (arch.lib.a) */
set_parent_cap_arch((void *)vaddr);
_daddr = vaddr;
}
void setup_text(addr_t vaddr, size_t size, off_t offset)
{
_vaddr = vaddr;
Rm_area::r()->attach_executable(_ds_rom, vaddr, size, offset);
}
addr_t alloc_region(addr_t vaddr, addr_t vlimit)
{
Rm_area *a = Rm_area::r(vaddr);
return a->alloc_region(vlimit - vaddr, vaddr);
}
static List<Fd_handle> *file_list()
{
static List<Fd_handle> _file_list;
return &_file_list;
}
static Fd_handle *find_handle(int fd, addr_t vaddr = 0)
{
Fd_handle *h = file_list()->first();
while (h) {
if (vaddr && vaddr == h->_vaddr)
return h;
if (h->_fd == fd)
return h;
h = h->next();
}
return 0;
}
static void free(void *addr)
{
addr_t vaddr = (addr_t) addr;
Fd_handle *h = file_list()->first();
while (h) {
if (h->_vaddr != vaddr) {
h = h->next();
continue;
}
destroy(env()->heap(), h);
return;
}
}
~Fd_handle()
{
file_list()->remove(this);
if (_vaddr != ~0UL) {
Rm_area::r()->detach(_vaddr);
Rm_area::r()->detach(_daddr);
Rm_area::r()->free_region(_vaddr);
env()->ram_session()->free(_ds_ram);
env()->rm_session()->detach(_phdr);
}
if (_rom_cap.valid())
env()->parent()->close(_rom_cap);
}
};
}
extern "C" int open(const char *pathname, int flags)
{
using namespace Genode;
static int fd = -1;
static int i = 0;
i++;
/* skip directory part from pathname, leaving only the plain filename */
const char *filename = pathname;
for (; *pathname; pathname++)
if (*pathname == '/')
filename = pathname + 1;
try {
/* open the file dataspace and attach it */
Rom_connection rom(filename);
rom.on_destruction(Rom_connection::KEEP_OPEN);
Fd_handle::file_list()->insert(new(env()->heap())
Fd_handle(++fd, rom.dataspace(), rom.cap()));
Fd_handle *h;
if (!(h = Fd_handle::find_handle(fd))) {
PERR("Could not open %s\n", filename);
return -1;
}
} catch (...) {
PERR("Rom connection failed for %s", filename);
return -1;
}
return fd;
}
extern "C" void *file_phdr(const char *pathname, void *vaddr)
{
using namespace Genode;
Fd_handle *h = 0;
if (!(h = Fd_handle::find_handle(-1, (addr_t)vaddr))) {
int fd = open(pathname, 0);
h = Fd_handle::find_handle(fd);
h->vaddr((addr_t)vaddr);
}
return (void *)h->phdr();
}
extern "C" int find_binary_name(int fd, char *buf, size_t buf_size)
{
using namespace Genode;
Fd_handle *h;
if (!(h = Fd_handle::find_handle(fd))) {
PERR("handle not found\n");
return -1;
}
return binary_name(h->dataspace(), buf, buf_size);
}
extern "C" ssize_t read(int fd, void *buf, size_t count)
{
using namespace Genode;
Fd_handle *h;
if (!(h = Fd_handle::find_handle(fd))) {
PERR("handle not found\n");
return -1;
}
try {
void *base = env()->rm_session()->attach(h->dataspace(), count);
memcpy(buf, base, count);
env()->rm_session()->detach(base);
}
catch (...) {
return -1;
}
return count;
}
extern "C" ssize_t write(int fd, const void *buf, size_t count)
{
Genode::printf("%p", buf);
return count;
}
extern "C" int munmap(void *addr, size_t /* length */)
{
using namespace Genode;
Fd_handle::free(addr);
return 0;
}
extern "C" void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
using namespace Genode;
if(!(flags & MAP_ANON)) {
PERR("No MAP_ANON");
return MAP_FAILED;
}
/* called during ldso relocation */
if (flags & MAP_LDSO) {
enum { MEM_SIZE = 128 * 1024 };
static char _mem[MEM_SIZE];
/* generate fault on allocation */
if (length > MEM_SIZE) {
int *fault = (int *)0xa110ce88;
*fault = 1;
}
return _mem;
}
/* memory allocation */
else {
void *base;
try {
Ram_dataspace_capability ds_cap = env()->ram_session()->alloc(round_page(length));
base = env()->rm_session()->attach(ds_cap, length, 0,
(addr) ? true : false, (addr_t)addr);
}
catch(...) {
PERR("Anonmymous mmap failed\n");
return MAP_FAILED;
}
if (debug)
PDBG("base %p", base);
return base;
}
return MAP_FAILED;
}
extern "C" void *genode_map(int fd, Elf_Phdr **segs)
{
using namespace Genode;
if (1 > 1) {
PERR("More than two segments in ELF");
return MAP_FAILED;
}
Fd_handle *h;
if (!(h = Fd_handle::find_handle(fd))) {
PERR("handle not found\n");
return MAP_FAILED;
}
addr_t base_vaddr = trunc_page(segs[0]->p_vaddr);
addr_t base_offset = trunc_page(segs[0]->p_offset);
addr_t base_msize = round_page(segs[1]->p_vaddr - base_vaddr);
addr_t base_vlimit = round_page(segs[1]->p_vaddr + segs[1]->p_memsz);
/* is this a fixed address */
bool fixed = base_vaddr ? true : false;
try {
base_vaddr = h->alloc_region(base_vaddr, base_vlimit);
} catch (...) {
PERR("Region allocation failed: %lx-%lx", base_vaddr, base_vlimit);
return MAP_FAILED;
}
/* map text segment */
h->setup_text(base_vaddr, base_msize, base_offset);
addr_t offset = fixed ? 0 : base_vaddr;
base_vlimit += offset;
addr_t base_flimit = offset + segs[1]->p_vaddr + segs[1]->p_filesz;
base_vaddr = offset + trunc_page(segs[1]->p_vaddr);
base_offset = trunc_page(segs[1]->p_offset);
/* copy data segment */
h->setup_data(base_vaddr, base_vlimit, base_flimit, base_offset);
return (void *)h->vaddr();
}

View File

@ -1,39 +0,0 @@
/*
* \brief Meta-information for Genode on Linux
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
* \date 2010-01-04
*/
/*
* Copyright (C) 2010-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _FILE_H_
#define _FILE_H_
#include <machine/elf.h>
#ifdef __cplusplus
extern "C" {
#endif
int find_binary_name(int fd, char *buf, size_t buf_size);
/**
* Map file into address space
*
* \param fd File handle
* \param segs Elf segment descriptors (must currently be two)
*
* \return Address on success; MAP_FAILED otherwise
*/
void *genode_map(int fd, Elf_Phdr **segs);
#ifdef __cplusplus
}
#endif
#endif /* _FILE_H_ */

View File

@ -1,139 +0,0 @@
/*-
* Copyright (c) 1994
* The Regents of the University of California. All rights reserved.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* $FreeBSD: src/include/dlfcn.h,v 1.20 2005/12/18 19:43:31 kan Exp $
*/
#ifndef _DLFCN_H_
#define _DLFCN_H_
#include <sys/_types.h>
/*
* Modes and flags for dlopen().
*/
#define RTLD_LAZY 1 /* Bind function calls lazily. */
#define RTLD_NOW 2 /* Bind function calls immediately. */
#define RTLD_MODEMASK 0x3
#define RTLD_GLOBAL 0x100 /* Make symbols globally available. */
#define RTLD_LOCAL 0 /* Opposite of RTLD_GLOBAL, and the default. */
#define RTLD_TRACE 0x200 /* Trace loaded objects and exit. */
/*
* Request arguments for dlinfo().
*/
#define RTLD_DI_LINKMAP 2 /* Obtain link map. */
#define RTLD_DI_SERINFO 4 /* Obtain search path info. */
#define RTLD_DI_SERINFOSIZE 5 /* ... query for required space. */
#define RTLD_DI_ORIGIN 6 /* Obtain object origin */
#define RTLD_DI_MAX RTLD_DI_ORIGIN
/*
* Special handle arguments for dlsym()/dlinfo().
*/
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search the caller itself. */
#if __BSD_VISIBLE
#ifndef _SIZE_T_DECLARED
typedef __size_t size_t;
#define _SIZE_T_DECLARED
#endif
/*
* Structure filled in by dladdr().
*/
typedef struct dl_info {
const char *dli_fname; /* Pathname of shared object. */
void *dli_fbase; /* Base address of shared object. */
const char *dli_sname; /* Name of nearest symbol. */
void *dli_saddr; /* Address of nearest symbol. */
} Dl_info;
/*-
* The actual type declared by this typedef is immaterial, provided that
* it is a function pointer. Its purpose is to provide a return type for
* dlfunc() which can be cast to a function pointer type without depending
* on behavior undefined by the C standard, which might trigger a compiler
* diagnostic. We intentionally declare a unique type signature to force
* a diagnostic should the application not cast the return value of dlfunc()
* appropriately.
*/
struct __dlfunc_arg {
int __dlfunc_dummy;
};
typedef void (*dlfunc_t)(struct __dlfunc_arg);
/*
* Structures, returned by the RTLD_DI_SERINFO dlinfo() request.
*/
typedef struct dl_serpath {
char * dls_name; /* single search path entry */
unsigned int dls_flags; /* path information */
} Dl_serpath;
typedef struct dl_serinfo {
size_t dls_size; /* total buffer size */
unsigned int dls_cnt; /* number of path entries */
Dl_serpath dls_serpath[1]; /* there may be more than one */
} Dl_serinfo;
#endif /* __BSD_VISIBLE */
__BEGIN_DECLS
/* XSI functions first. */
int dlclose(void *);
const char *
dlerror(void);
void *dlopen(const char *, int);
void *dlsym(void * __restrict, const char * __restrict);
#if __BSD_VISIBLE
int dladdr(const void * __restrict, Dl_info * __restrict);
dlfunc_t dlfunc(void * __restrict, const char * __restrict);
int dlinfo(void * __restrict, int, void * __restrict);
void dllockinit(void *_context,
void *(*_lock_create)(void *_context),
void (*_rlock_acquire)(void *_lock),
void (*_wlock_acquire)(void *_lock),
void (*_lock_release)(void *_lock),
void (*_lock_destroy)(void *_lock),
void (*_context_destroy)(void *_context));
void *dlvsym(void * __restrict, const char * __restrict,
const char * __restrict);
#endif /* __BSD_VISIBLE */
__END_DECLS
#endif /* !_DLFCN_H_ */

View File

@ -1,50 +0,0 @@
/*-
* Copyright (c) 1997 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/include/elf-hints.h,v 1.4 2001/05/02 23:56:17 obrien Exp $
*/
#ifndef _ELF_HINTS_H_
#define _ELF_HINTS_H_
/*
* Hints file produced by ldconfig.
*/
struct elfhints_hdr {
u_int32_t magic; /* Magic number */
u_int32_t version; /* File version (1) */
u_int32_t strtab; /* Offset of string table in file */
u_int32_t strsize; /* Size of string table */
u_int32_t dirlist; /* Offset of directory list in
string table */
u_int32_t dirlistlen; /* strlen(dirlist) */
u_int32_t spare[26]; /* Room for expansion */
};
#define ELFHINTS_MAGIC 0x746e6845
#define _PATH_ELF_HINTS "/var/run/ld-elf.so.hints"
#endif /* !_ELF_HINTS_H_ */

View File

@ -1,123 +0,0 @@
/*-
* Copyright (c) 1996-1997 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/amd64/include/elf.h,v 1.19 2006/10/04 21:37:09 jb Exp $
*/
#ifndef _MACHINE_ELF_H_
#define _MACHINE_ELF_H_ 1
/*
* ELF definitions for the AMD64 architecture.
*/
#ifndef __ELF_WORD_SIZE
#define __ELF_WORD_SIZE 64 /* Used by <sys/elf_generic.h> */
#endif
#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
#include <sys/elf_generic.h>
#define ELF_ARCH EM_X86_64
#define ELF_MACHINE_OK(x) ((x) == EM_X86_64)
/*
* Auxiliary vector entries for passing information to the interpreter.
*
* The i386 supplement to the SVR4 ABI specification names this "auxv_t",
* but POSIX lays claim to all symbols ending with "_t".
*/
typedef struct { /* Auxiliary vector entry on initial stack */
int a_type; /* Entry type. */
union {
int a_val; /* Integer value. */
} a_un;
} Elf32_Auxinfo;
typedef struct { /* Auxiliary vector entry on initial stack */
long a_type; /* Entry type. */
union {
long a_val; /* Integer value. */
void *a_ptr; /* Address. */
void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
} Elf64_Auxinfo;
__ElfType(Auxinfo);
/* Values for a_type. */
#define AT_NULL 0 /* Terminates the vector. */
#define AT_IGNORE 1 /* Ignored entry. */
#define AT_EXECFD 2 /* File descriptor of program to load. */
#define AT_PHDR 3 /* Program header of program already loaded. */
#define AT_PHENT 4 /* Size of each program header entry. */
#define AT_PHNUM 5 /* Number of program header entries. */
#define AT_PAGESZ 6 /* Page size in bytes. */
#define AT_BASE 7 /* Interpreter's base address. */
#define AT_FLAGS 8 /* Flags (unused for i386). */
#define AT_ENTRY 9 /* Where interpreter should transfer control. */
/*
* The following non-standard values are used for passing information
* from John Polstra's testbed program to the dynamic linker. These
* are expected to go away soon.
*
* Unfortunately, these overlap the Linux non-standard values, so they
* must not be used in the same context.
*/
#define AT_BRK 10 /* Starting point for sbrk and brk. */
#define AT_DEBUG 11 /* Debugging level. */
/*
* The following non-standard values are used in Linux ELF binaries.
*/
#define AT_NOTELF 10 /* Program is not ELF ?? */
#define AT_UID 11 /* Real uid. */
#define AT_EUID 12 /* Effective uid. */
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_COUNT 15 /* Count of defined aux entry types. */
/*
* Relocation types.
*/
#define R_X86_64_COUNT 24 /* Count of defined relocation types. */
/* Define "machine" characteristics */
#if __ELF_WORD_SIZE == 32
#define ELF_TARG_CLASS ELFCLASS32
#else
#define ELF_TARG_CLASS ELFCLASS64
#endif
#define ELF_TARG_DATA ELFDATA2LSB
#define ELF_TARG_MACH EM_X86_64
#define ELF_TARG_VER 1
#endif /* !_MACHINE_ELF_H_ */

View File

@ -1,174 +0,0 @@
/* $NetBSD: asm.h,v 1.5 2003/08/07 16:26:53 agc Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* 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. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* from: @(#)asm.h 5.5 (Berkeley) 5/7/91
*
* $FreeBSD: src/sys/arm/include/asm.h,v 1.7 2007/10/13 12:04:10 cognet Exp $
*/
#ifndef _MACHINE_ASM_H_
#define _MACHINE_ASM_H_
#include <sys/cdefs.h>
#ifdef __ELF__
# define _C_LABEL(x) x
#else
# ifdef __STDC__
# define _C_LABEL(x) _ ## x
# else
# define _C_LABEL(x) _/**/x
# endif
#endif
#define _ASM_LABEL(x) x
#ifndef _JB_MAGIC__SETJMP
#define _JB_MAGIC__SETJMP 0x4278f500
#define _JB_MAGIC_SETJMP 0x4278f501
#endif
#define I32_bit (1 << 7) /* IRQ disable */
#define F32_bit (1 << 6) /* FIQ disable */
#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */
#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */
#ifndef _ALIGN_TEXT
# define _ALIGN_TEXT .align 0
#endif
/*
* gas/arm uses @ as a single comment character and thus cannot be used here
* Instead it recognised the # instead of an @ symbols in .type directives
* We define a couple of macros so that assembly code will not be dependant
* on one or the other.
*/
#define _ASM_TYPE_FUNCTION #function
#define _ASM_TYPE_OBJECT #object
#define GLOBAL(X) .globl x
#define _ENTRY(x) \
.text; _ALIGN_TEXT; .globl x; .type x,_ASM_TYPE_FUNCTION; x:
#ifdef GPROF
# define _PROF_PROLOGUE \
mov ip, lr; bl __mcount
#else
# define _PROF_PROLOGUE
#endif
#define ENTRY(y) _ENTRY(_C_LABEL(y)); _PROF_PROLOGUE
#define ENTRY_NP(y) _ENTRY(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y)); _PROF_PROLOGUE
#define ASENTRY_NP(y) _ENTRY(_ASM_LABEL(y))
#define ASMSTR .asciz
#if defined(__ELF__) && defined(PIC)
#ifdef __STDC__
#define PIC_SYM(x,y) x ## ( ## y ## )
#else
#define PIC_SYM(x,y) x/**/(/**/y/**/)
#endif
#else
#define PIC_SYM(x,y) x
#endif
#undef __FBSDID
#if !defined(lint) && !defined(STRIP_FBSDID)
#define __FBSDID(s) .ident s
#else
#define __FBSDID(s) /* nothing */
#endif
#ifdef __ELF__
#define WEAK_ALIAS(alias,sym) \
.weak alias; \
alias = sym
#endif
#ifdef __STDC__
#define WARN_REFERENCES(sym,msg) \
.stabs msg ## ,30,0,0,0 ; \
.stabs __STRING(_C_LABEL(sym)) ## ,1,0,0,0
#elif defined(__ELF__)
#define WARN_REFERENCES(sym,msg) \
.stabs msg,30,0,0,0 ; \
.stabs __STRING(sym),1,0,0,0
#else
#define WARN_REFERENCES(sym,msg) \
.stabs msg,30,0,0,0 ; \
.stabs __STRING(_/**/sym),1,0,0,0
#endif /* __STDC__ */
#if defined (__ARM_ARCH_6__) || defined (__ARM_ARCH_6J__)
#define _ARM_ARCH_6
#endif
#if defined (_ARM_ARCH_6) || defined (__ARM_ARCH_5__) || \
defined (__ARM_ARCH_5T__) || defined (__ARM_ARCH_5TE__) || \
defined (__ARM_ARCH_5TEJ__) || defined (__ARM_ARCH_5E__)
#define _ARM_ARCH_5
#endif
#if defined (_ARM_ARCH_6) || defined(__ARM_ARCH_5TE__) || \
defined(__ARM_ARCH_5TEJ__) || defined(__ARM_ARCH_5E__)
#define _ARM_ARCH_5E
#endif
#if defined (_ARM_ARCH_5) || defined (__ARM_ARCH_4T__)
#define _ARM_ARCH_4T
#endif
#if defined (_ARM_ARCH_4T)
# define RET bx lr
# define RETeq bxeq lr
# define RETne bxne lr
# ifdef __STDC__
# define RETc(c) bx##c lr
# else
# define RETc(c) bx/**/c lr
# endif
#else
# define RET mov pc, lr
# define RETeq moveq pc, lr
# define RETne movne pc, lr
# ifdef __STDC__
# define RETc(c) mov##c pc, lr
# else
# define RETc(c) mov/**/c pc, lr
# endif
#endif
#endif /* !_MACHINE_ASM_H_ */

View File

@ -1,103 +0,0 @@
/*-
* Copyright (c) 2001 David E. O'Brien
* Copyright (c) 1996-1997 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/arm/include/elf.h,v 1.11 2009/10/10 15:31:24 kib Exp $
*/
#ifndef _MACHINE_ELF_H_
#define _MACHINE_ELF_H_ 1
/*
* EABI ELF definitions for the StrongARM architecture.
* See "ARM ELF", document no. `SWS ESPC 0003 A-08' for details.
*/
#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
#define __ELF_WORD_SIZE 32 /* Used by <sys/elf_generic.h> */
#include <sys/elf_generic.h>
typedef struct { /* Auxiliary vector entry on initial stack */
int a_type; /* Entry type. */
union {
long a_val; /* Integer value. */
void *a_ptr; /* Address. */
void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
} Elf32_Auxinfo;
__ElfType(Auxinfo);
#define ELF_ARCH EM_ARM
#define ELF_MACHINE_OK(x) ((x) == EM_ARM)
/*
* Relocation types.
*/
/* Values for a_type. */
#define AT_NULL 0 /* Terminates the vector. */
#define AT_IGNORE 1 /* Ignored entry. */
#define AT_EXECFD 2 /* File descriptor of program to load. */
#define AT_PHDR 3 /* Program header of program already loaded. */
#define AT_PHENT 4 /* Size of each program header entry. */
#define AT_PHNUM 5 /* Number of program header entries. */
#define AT_PAGESZ 6 /* Page size in bytes. */
#define AT_BASE 7 /* Interpreter's base address. */
#define AT_FLAGS 8 /* Flags (unused). */
#define AT_ENTRY 9 /* Where interpreter should transfer control. */
#define AT_NOTELF 10 /* Program is not ELF ?? */
#define AT_UID 11 /* Real uid. */
#define AT_EUID 12 /* Effective uid. */
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_EXECPATH 15 /* Path to the executable. */
#define AT_COUNT 16 /* Count of defined aux entry types. */
#define R_ARM_COUNT 33 /* Count of defined relocation types. */
/* Define "machine" characteristics */
#define ELF_TARG_CLASS ELFCLASS32
#ifdef __ARMEB__
#define ELF_TARG_DATA ELFDATA2MSB
#else
#define ELF_TARG_DATA ELFDATA2LSB
#endif
#define ELF_TARG_MACH EM_ARM
#define ELF_TARG_VER 1
/*
* Magic number for the elf trampoline, chosen wisely to be an immediate
* value.
*/
#define MAGIC_TRAMP_NUMBER 0x5c000003
#define ET_DYN_LOAD_ADDR 0x12000
#endif /* !_MACHINE_ELF_H_ */

View File

@ -1,122 +0,0 @@
/*-
* Copyright (c) 1996-1997 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/i386/include/elf.h,v 1.17 2006/10/04 21:37:09 jb Exp $
*/
#ifndef _MACHINE_ELF_H_
#define _MACHINE_ELF_H_ 1
/*
* ELF definitions for the i386 architecture.
*/
#include <sys/elf32.h> /* Definitions common to all 32 bit architectures. */
#if defined(__ELF_WORD_SIZE) && __ELF_WORD_SIZE == 64
#include <sys/elf64.h> /* Definitions common to all 64 bit architectures. */
#endif
#ifndef __ELF_WORD_SIZE
#define __ELF_WORD_SIZE 32 /* Used by <sys/elf_generic.h> */
#endif
#include <sys/elf_generic.h>
#define ELF_ARCH EM_386
#define ELF_MACHINE_OK(x) ((x) == EM_386 || (x) == EM_486)
/*
* Auxiliary vector entries for passing information to the interpreter.
*
* The i386 supplement to the SVR4 ABI specification names this "auxv_t",
* but POSIX lays claim to all symbols ending with "_t".
*/
typedef struct { /* Auxiliary vector entry on initial stack */
int a_type; /* Entry type. */
union {
long a_val; /* Integer value. */
void *a_ptr; /* Address. */
void (*a_fcn)(void); /* Function pointer (not used). */
} a_un;
} Elf32_Auxinfo;
#if __ELF_WORD_SIZE == 64
/* Fake for amd64 loader support */
typedef struct {
int fake;
} Elf64_Auxinfo;
#endif
__ElfType(Auxinfo);
/* Values for a_type. */
#define AT_NULL 0 /* Terminates the vector. */
#define AT_IGNORE 1 /* Ignored entry. */
#define AT_EXECFD 2 /* File descriptor of program to load. */
#define AT_PHDR 3 /* Program header of program already loaded. */
#define AT_PHENT 4 /* Size of each program header entry. */
#define AT_PHNUM 5 /* Number of program header entries. */
#define AT_PAGESZ 6 /* Page size in bytes. */
#define AT_BASE 7 /* Interpreter's base address. */
#define AT_FLAGS 8 /* Flags (unused for i386). */
#define AT_ENTRY 9 /* Where interpreter should transfer control. */
/*
* The following non-standard values are used for passing information
* from John Polstra's testbed program to the dynamic linker. These
* are expected to go away soon.
*
* Unfortunately, these overlap the Linux non-standard values, so they
* must not be used in the same context.
*/
#define AT_BRK 10 /* Starting point for sbrk and brk. */
#define AT_DEBUG 11 /* Debugging level. */
/*
* The following non-standard values are used in Linux ELF binaries.
*/
#define AT_NOTELF 10 /* Program is not ELF ?? */
#define AT_UID 11 /* Real uid. */
#define AT_EUID 12 /* Effective uid. */
#define AT_GID 13 /* Real gid. */
#define AT_EGID 14 /* Effective gid. */
#define AT_COUNT 15 /* Count of defined aux entry types. */
/*
* Relocation types.
*/
#define R_386_COUNT 38 /* Count of defined relocation types. */
/* Define "machine" characteristics */
#define ELF_TARG_CLASS ELFCLASS32
#define ELF_TARG_DATA ELFDATA2LSB
#define ELF_TARG_MACH EM_386
#define ELF_TARG_VER 1
#endif /* !_MACHINE_ELF_H_ */

View File

@ -1,564 +0,0 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Berkeley Software Design, Inc.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
* $FreeBSD: src/sys/sys/cdefs.h,v 1.96 2008/10/21 16:46:50 rdivacky Exp $
*/
#ifndef _SYS_CDEFS_H_
#define _SYS_CDEFS_H_
#if defined(__cplusplus)
#define __BEGIN_DECLS extern "C" {
#define __END_DECLS }
#else
#define __BEGIN_DECLS
#define __END_DECLS
#endif
/*
* This code has been put in place to help reduce the addition of
* compiler specific defines in FreeBSD code. It helps to aid in
* having a compiler-agnostic source tree.
*/
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
#if __GNUC__ >= 3 || defined(__INTEL_COMPILER)
#define __GNUCLIKE_ASM 3
#define __GNUCLIKE_MATH_BUILTIN_CONSTANTS
#else
#define __GNUCLIKE_ASM 2
#endif
#define __GNUCLIKE___TYPEOF 1
#define __GNUCLIKE___OFFSETOF 1
#define __GNUCLIKE___SECTION 1
#define __GNUCLIKE_ATTRIBUTE_MODE_DI 1
#ifndef __INTEL_COMPILER
# define __GNUCLIKE_CTOR_SECTION_HANDLING 1
#endif
#define __GNUCLIKE_BUILTIN_CONSTANT_P 1
# if defined(__INTEL_COMPILER) && defined(__cplusplus) \
&& __INTEL_COMPILER < 800
# undef __GNUCLIKE_BUILTIN_CONSTANT_P
# endif
#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3) && !defined(__INTEL_COMPILER)
# define __GNUCLIKE_BUILTIN_VARARGS 1
# define __GNUCLIKE_BUILTIN_STDARG 1
# define __GNUCLIKE_BUILTIN_VAALIST 1
#endif
#if defined(__GNUC__)
# define __GNUC_VA_LIST_COMPATIBILITY 1
#endif
#ifndef __INTEL_COMPILER
# define __GNUCLIKE_BUILTIN_NEXT_ARG 1
# define __GNUCLIKE_MATH_BUILTIN_RELOPS
#endif
#define __GNUCLIKE_BUILTIN_MEMCPY 1
/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */
#define __CC_SUPPORTS_INLINE 1
#define __CC_SUPPORTS___INLINE 1
#define __CC_SUPPORTS___INLINE__ 1
#define __CC_SUPPORTS___FUNC__ 1
#define __CC_SUPPORTS_WARNING 1
#define __CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */
#define __CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1
#endif /* __GNUC__ || __INTEL_COMPILER */
/*
* Macro to test if we're using a specific version of gcc or later.
*/
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
#define __GNUC_PREREQ__(ma, mi) \
(__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
#else
#define __GNUC_PREREQ__(ma, mi) 0
#endif
/*
* The __CONCAT macro is used to concatenate parts of symbol names, e.g.
* with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
* The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
* mode -- there must be no spaces between its arguments, and for nested
* __CONCAT's, all the __CONCAT's must be at the left. __CONCAT can also
* concatenate double-quoted strings produced by the __STRING macro, but
* this only works with ANSI C.
*
* __XSTRING is like __STRING, but it expands any macros in its argument
* first. It is only available with ANSI C.
*/
#if defined(__STDC__) || defined(__cplusplus)
#define __P(protos) protos /* full-blown ANSI C */
#define __CONCAT1(x,y) x ## y
#define __CONCAT(x,y) __CONCAT1(x,y)
#define __STRING(x) #x /* stringify without expanding x */
#define __XSTRING(x) __STRING(x) /* expand x, then stringify */
#define __const const /* define reserved names to standard */
#define __signed signed
#define __volatile volatile
#if defined(__cplusplus)
#define __inline inline /* convert to C++ keyword */
#else
#if !(defined(__CC_SUPPORTS___INLINE))
#define __inline /* delete GCC keyword */
#endif /* ! __CC_SUPPORTS___INLINE */
#endif /* !__cplusplus */
#else /* !(__STDC__ || __cplusplus) */
#define __P(protos) () /* traditional C preprocessor */
#define __CONCAT(x,y) x/**/y
#define __STRING(x) "x"
#if !defined(__CC_SUPPORTS___INLINE)
#define __const /* delete pseudo-ANSI C keywords */
#define __inline
#define __signed
#define __volatile
/*
* In non-ANSI C environments, new programs will want ANSI-only C keywords
* deleted from the program and old programs will want them left alone.
* When using a compiler other than gcc, programs using the ANSI C keywords
* const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
* When using "gcc -traditional", we assume that this is the intent; if
* __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
*/
#ifndef NO_ANSI_KEYWORDS
#define const /* delete ANSI C keywords */
#define inline
#define signed
#define volatile
#endif /* !NO_ANSI_KEYWORDS */
#endif /* !__CC_SUPPORTS___INLINE */
#endif /* !(__STDC__ || __cplusplus) */
/*
* Compiler-dependent macros to help declare dead (non-returning) and
* pure (no side effects) functions, and unused variables. They are
* null except for versions of gcc that are known to support the features
* properly (old versions of gcc-2 supported the dead and pure features
* in a different (wrong) way). If we do not provide an implementation
* for a given compiler, let the compile fail if it is told to use
* a feature that we cannot live without.
*/
#ifdef lint
#define __dead2
#define __pure2
#define __unused
#define __packed
#define __aligned(x)
#define __section(x)
#else
#if !__GNUC_PREREQ__(2, 5) && !defined(__INTEL_COMPILER)
#define __dead2
#define __pure2
#define __unused
#endif
#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7 && !defined(__INTEL_COMPILER)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused
/* XXX Find out what to do for __packed, __aligned and __section */
#endif
#if __GNUC_PREREQ__(2, 7)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
#define __packed __attribute__((__packed__))
#define __aligned(x) __attribute__((__aligned__(x)))
#define __section(x) __attribute__((__section__(x)))
#endif
#if defined(__INTEL_COMPILER)
#define __dead2 __attribute__((__noreturn__))
#define __pure2 __attribute__((__const__))
#define __unused __attribute__((__unused__))
#define __used __attribute__((__used__))
#define __packed __attribute__((__packed__))
#define __aligned(x) __attribute__((__aligned__(x)))
#define __section(x) __attribute__((__section__(x)))
#endif
#endif
#if __GNUC_PREREQ__(2, 96)
#define __pure __attribute__((__pure__))
#else
#define __pure
#endif
#if __GNUC_PREREQ__(3, 1) || (defined(__INTEL_COMPILER) && __INTEL_COMPILER >= 800)
#define __always_inline __attribute__((__always_inline__))
#else
#define __always_inline
#endif
#if __GNUC_PREREQ__(4, 2) /* actually 4.1.3 */
#define __gnu89_inline __attribute__((__gnu_inline__)) __inline
#else
#define __gnu89_inline
#endif
#if __GNUC_PREREQ__(3, 1)
#define __noinline __attribute__ ((__noinline__))
#else
#define __noinline
#endif
#if __GNUC_PREREQ__(3, 3)
#define __nonnull(x) __attribute__((__nonnull__(x)))
#else
#define __nonnull(x)
#endif
/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
#define __func__ NULL
#endif
#if (defined(__INTEL_COMPILER) || (defined(__GNUC__) && __GNUC__ >= 2)) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
#define __LONG_LONG_SUPPORTED
#endif
/*
* GCC 2.95 provides `__restrict' as an extension to C90 to support the
* C99-specific `restrict' type qualifier. We happen to use `__restrict' as
* a way to define the `restrict' type qualifier without disturbing older
* software that is unaware of C99 keywords.
*/
#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
#define __restrict
#else
#define __restrict restrict
#endif
#endif
/*
* GNU C version 2.96 adds explicit branch prediction so that
* the CPU back-end can hint the processor and also so that
* code blocks can be reordered such that the predicted path
* sees a more linear flow, thus improving cache behavior, etc.
*
* The following two macros provide us with a way to utilize this
* compiler feature. Use __predict_true() if you expect the expression
* to evaluate to true, and __predict_false() if you expect the
* expression to evaluate to false.
*
* A few notes about usage:
*
* * Generally, __predict_false() error condition checks (unless
* you have some _strong_ reason to do otherwise, in which case
* document it), and/or __predict_true() `no-error' condition
* checks, assuming you want to optimize for the no-error case.
*
* * Other than that, if you don't know the likelihood of a test
* succeeding from empirical or other `hard' evidence, don't
* make predictions.
*
* * These are meant to be used in places that are run `a lot'.
* It is wasteful to make predictions in code that is run
* seldomly (e.g. at subsystem initialization time) as the
* basic block reordering that this affects can often generate
* larger code.
*/
#if __GNUC_PREREQ__(2, 96)
#define __predict_true(exp) __builtin_expect((exp), 1)
#define __predict_false(exp) __builtin_expect((exp), 0)
#else
#define __predict_true(exp) (exp)
#define __predict_false(exp) (exp)
#endif
/*
* We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
* require it.
*/
#if __GNUC_PREREQ__(4, 1)
#define __offsetof(type, field) __builtin_offsetof(type, field)
#else
#ifndef __cplusplus
#define __offsetof(type, field) ((size_t)(&((type *)0)->field))
#else
#define __offsetof(type, field) \
(__offsetof__ (reinterpret_cast <size_t> \
(&reinterpret_cast <const volatile char &> \
(static_cast<type *> (0)->field))))
#endif
#endif
#define __rangeof(type, start, end) \
(__offsetof(type, end) - __offsetof(type, start))
/*
* Compiler-dependent macros to declare that functions take printf-like
* or scanf-like arguments. They are null except for versions of gcc
* that are known to support the features properly (old versions of gcc-2
* didn't permit keeping the keywords out of the application namespace).
*/
#if !__GNUC_PREREQ__(2, 7) && !defined(__INTEL_COMPILER)
#define __printflike(fmtarg, firstvararg)
#define __scanflike(fmtarg, firstvararg)
#define __format_arg(fmtarg)
#else
#define __printflike(fmtarg, firstvararg) \
__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
#define __scanflike(fmtarg, firstvararg) \
__attribute__((__format__ (__scanf__, fmtarg, firstvararg)))
#define __format_arg(fmtarg) __attribute__((__format_arg__ (fmtarg)))
#endif
/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
#if __FreeBSD_cc_version >= 300001 && defined(__GNUC__) && !defined(__INTEL_COMPILER)
#define __printf0like(fmtarg, firstvararg) \
__attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
#else
#define __printf0like(fmtarg, firstvararg)
#endif
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
#ifndef __INTEL_COMPILER
#define __strong_reference(sym,aliassym) \
extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
#endif
#ifdef __STDC__
#define __weak_reference(sym,alias) \
__asm__(".weak " #alias); \
__asm__(".equ " #alias ", " #sym)
#define __warn_references(sym,msg) \
__asm__(".section .gnu.warning." #sym); \
__asm__(".asciz \"" msg "\""); \
__asm__(".previous")
#define __sym_compat(sym,impl,verid) \
__asm__(".symver " #impl ", " #sym "@" #verid)
#define __sym_default(sym,impl,verid) \
__asm__(".symver " #impl ", " #sym "@@" #verid)
#else
#define __weak_reference(sym,alias) \
__asm__(".weak alias"); \
__asm__(".equ alias, sym")
#define __warn_references(sym,msg) \
__asm__(".section .gnu.warning.sym"); \
__asm__(".asciz \"msg\""); \
__asm__(".previous")
#define __sym_compat(sym,impl,verid) \
__asm__(".symver impl, sym@verid")
#define __sym_default(impl,sym,verid) \
__asm__(".symver impl, sym@@verid")
#endif /* __STDC__ */
#endif /* __GNUC__ || __INTEL_COMPILER */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
#define __IDSTRING(name,string) __asm__(".ident\t\"" string "\"")
#else
/*
* The following definition might not work well if used in header files,
* but it should be better than nothing. If you want a "do nothing"
* version, then it should generate some harmless declaration, such as:
* #define __IDSTRING(name,string) struct __hack
*/
#define __IDSTRING(name,string) static const char name[] __unused = string
#endif
/*
* Embed the rcs id of a source file in the resulting library. Note that in
* more recent ELF binutils, we use .ident allowing the ID to be stripped.
* Usage:
* __FBSDID("$FreeBSD: src/sys/sys/cdefs.h,v 1.96 2008/10/21 16:46:50 rdivacky Exp $");
*/
#ifndef __FBSDID
#if !defined(lint) && !defined(STRIP_FBSDID)
#define __FBSDID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
#else
#define __FBSDID(s) struct __hack
#endif
#endif
#ifndef __RCSID
#ifndef NO__RCSID
#define __RCSID(s) __IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
#else
#define __RCSID(s) struct __hack
#endif
#endif
#ifndef __RCSID_SOURCE
#ifndef NO__RCSID_SOURCE
#define __RCSID_SOURCE(s) __IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
#else
#define __RCSID_SOURCE(s) struct __hack
#endif
#endif
#ifndef __SCCSID
#ifndef NO__SCCSID
#define __SCCSID(s) __IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
#else
#define __SCCSID(s) struct __hack
#endif
#endif
#ifndef __COPYRIGHT
#ifndef NO__COPYRIGHT
#define __COPYRIGHT(s) __IDSTRING(__CONCAT(__copyright_,__LINE__),s)
#else
#define __COPYRIGHT(s) struct __hack
#endif
#endif
#ifndef __DECONST
#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
#endif
#ifndef __DEVOLATILE
#define __DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var))
#endif
#ifndef __DEQUALIFY
#define __DEQUALIFY(type, var) ((type)(uintptr_t)(const volatile void *)(var))
#endif
/*-
* The following definitions are an extension of the behavior originally
* implemented in <sys/_posix.h>, but with a different level of granularity.
* POSIX.1 requires that the macros we test be defined before any standard
* header file is included.
*
* Here's a quick run-down of the versions:
* defined(_POSIX_SOURCE) 1003.1-1988
* _POSIX_C_SOURCE == 1 1003.1-1990
* _POSIX_C_SOURCE == 2 1003.2-1992 C Language Binding Option
* _POSIX_C_SOURCE == 199309 1003.1b-1993
* _POSIX_C_SOURCE == 199506 1003.1c-1995, 1003.1i-1995,
* and the omnibus ISO/IEC 9945-1: 1996
* _POSIX_C_SOURCE == 200112 1003.1-2001
*
* In addition, the X/Open Portability Guide, which is now the Single UNIX
* Specification, defines a feature-test macro which indicates the version of
* that specification, and which subsumes _POSIX_C_SOURCE.
*
* Our macros begin with two underscores to avoid namespace screwage.
*/
/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
#undef _POSIX_C_SOURCE /* Probably illegal, but beyond caring now. */
#define _POSIX_C_SOURCE 199009
#endif
/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199209
#endif
/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
#ifdef _XOPEN_SOURCE
#if _XOPEN_SOURCE - 0 >= 600
#define __XSI_VISIBLE 600
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112
#elif _XOPEN_SOURCE - 0 >= 500
#define __XSI_VISIBLE 500
#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199506
#endif
#endif
/*
* Deal with all versions of POSIX. The ordering relative to the tests above is
* important.
*/
#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 198808
#endif
#ifdef _POSIX_C_SOURCE
#if _POSIX_C_SOURCE >= 200112
#define __POSIX_VISIBLE 200112
#define __ISO_C_VISIBLE 1999
#elif _POSIX_C_SOURCE >= 199506
#define __POSIX_VISIBLE 199506
#define __ISO_C_VISIBLE 1990
#elif _POSIX_C_SOURCE >= 199309
#define __POSIX_VISIBLE 199309
#define __ISO_C_VISIBLE 1990
#elif _POSIX_C_SOURCE >= 199209
#define __POSIX_VISIBLE 199209
#define __ISO_C_VISIBLE 1990
#elif _POSIX_C_SOURCE >= 199009
#define __POSIX_VISIBLE 199009
#define __ISO_C_VISIBLE 1990
#else
#define __POSIX_VISIBLE 198808
#define __ISO_C_VISIBLE 0
#endif /* _POSIX_C_SOURCE */
#else
/*-
* Deal with _ANSI_SOURCE:
* If it is defined, and no other compilation environment is explicitly
* requested, then define our internal feature-test macros to zero. This
* makes no difference to the preprocessor (undefined symbols in preprocessing
* expressions are defined to have value zero), but makes it more convenient for
* a test program to print out the values.
*
* If a program mistakenly defines _ANSI_SOURCE and some other macro such as
* _POSIX_C_SOURCE, we will assume that it wants the broader compilation
* environment (and in fact we will never get here).
*/
#if defined(_ANSI_SOURCE) /* Hide almost everything. */
#define __POSIX_VISIBLE 0
#define __XSI_VISIBLE 0
#define __BSD_VISIBLE 0
#define __ISO_C_VISIBLE 1990
#elif defined(_C99_SOURCE) /* Localism to specify strict C99 env. */
#define __POSIX_VISIBLE 0
#define __XSI_VISIBLE 0
#define __BSD_VISIBLE 0
#define __ISO_C_VISIBLE 1999
#else /* Default environment: show everything. */
#define __POSIX_VISIBLE 200112
#define __XSI_VISIBLE 600
#define __BSD_VISIBLE 1
#define __ISO_C_VISIBLE 1999
#endif
#endif
#endif /* !_SYS_CDEFS_H_ */

View File

@ -1,41 +0,0 @@
/*-
* Copyright (c) 2001 David E. O'Brien.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/sys/elf.h,v 1.2 2007/11/28 21:54:46 jb Exp $
*/
/*
* This is a Solaris compatibility header
*/
#ifndef _SYS_ELF_H_
#define _SYS_ELF_H_
#include <sys/types.h>
#include <machine/elf.h>
#include <sys/elf32.h>
#include <sys/elf64.h>
#endif /* !_SYS_ELF_H_ */

View File

@ -1,245 +0,0 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/sys/elf32.h,v 1.13 2006/10/17 05:43:30 jkoshy Exp $
*/
#ifndef _SYS_ELF32_H_
#define _SYS_ELF32_H_ 1
#include <sys/elf_common.h>
/*
* ELF definitions common to all 32-bit architectures.
*/
typedef uint32_t Elf32_Addr;
typedef uint16_t Elf32_Half;
typedef uint32_t Elf32_Off;
typedef int32_t Elf32_Sword;
typedef uint32_t Elf32_Word;
typedef uint64_t Elf32_Lword;
typedef Elf32_Word Elf32_Hashelt;
/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf32_Word Elf32_Size;
typedef Elf32_Sword Elf32_Ssize;
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf32_Half e_type; /* File type. */
Elf32_Half e_machine; /* Machine architecture. */
Elf32_Word e_version; /* ELF format version. */
Elf32_Addr e_entry; /* Entry point. */
Elf32_Off e_phoff; /* Program header file offset. */
Elf32_Off e_shoff; /* Section header file offset. */
Elf32_Word e_flags; /* Architecture-specific flags. */
Elf32_Half e_ehsize; /* Size of ELF header in bytes. */
Elf32_Half e_phentsize; /* Size of program header entry. */
Elf32_Half e_phnum; /* Number of program header entries. */
Elf32_Half e_shentsize; /* Size of section header entry. */
Elf32_Half e_shnum; /* Number of section header entries. */
Elf32_Half e_shstrndx; /* Section name strings section. */
} Elf32_Ehdr;
/*
* Section header.
*/
typedef struct {
Elf32_Word sh_name; /* Section name (index into the
section header string table). */
Elf32_Word sh_type; /* Section type. */
Elf32_Word sh_flags; /* Section flags. */
Elf32_Addr sh_addr; /* Address in memory image. */
Elf32_Off sh_offset; /* Offset in file. */
Elf32_Word sh_size; /* Size in bytes. */
Elf32_Word sh_link; /* Index of a related section. */
Elf32_Word sh_info; /* Depends on section type. */
Elf32_Word sh_addralign; /* Alignment in bytes. */
Elf32_Word sh_entsize; /* Size of each entry in section. */
} Elf32_Shdr;
/*
* Program header.
*/
typedef struct {
Elf32_Word p_type; /* Entry type. */
Elf32_Off p_offset; /* File offset of contents. */
Elf32_Addr p_vaddr; /* Virtual address in memory image. */
Elf32_Addr p_paddr; /* Physical address (not used). */
Elf32_Word p_filesz; /* Size of contents in file. */
Elf32_Word p_memsz; /* Size of contents in memory. */
Elf32_Word p_flags; /* Access permission flags. */
Elf32_Word p_align; /* Alignment in memory and file. */
} Elf32_Phdr;
/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/
typedef struct {
Elf32_Sword d_tag; /* Entry type. */
union {
Elf32_Word d_val; /* Integer value. */
Elf32_Addr d_ptr; /* Address value. */
} d_un;
} Elf32_Dyn;
/*
* Relocation entries.
*/
/* Relocations that don't need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
} Elf32_Rel;
/* Relocations that need an addend field. */
typedef struct {
Elf32_Addr r_offset; /* Location to be relocated. */
Elf32_Word r_info; /* Relocation type and symbol index. */
Elf32_Sword r_addend; /* Addend. */
} Elf32_Rela;
/* Macros for accessing the fields of r_info. */
#define ELF32_R_SYM(info) ((info) >> 8)
#define ELF32_R_TYPE(info) ((unsigned char)(info))
/* Macro for constructing r_info from field values. */
#define ELF32_R_INFO(sym, type) (((sym) << 8) + (unsigned char)(type))
/*
* Note entry header
*/
typedef Elf_Note Elf32_Nhdr;
/*
* Move entry
*/
typedef struct {
Elf32_Lword m_value; /* symbol value */
Elf32_Word m_info; /* size + index */
Elf32_Word m_poffset; /* symbol offset */
Elf32_Half m_repeat; /* repeat count */
Elf32_Half m_stride; /* stride info */
} Elf32_Move;
/*
* The macros compose and decompose values for Move.r_info
*
* sym = ELF32_M_SYM(M.m_info)
* size = ELF32_M_SIZE(M.m_info)
* M.m_info = ELF32_M_INFO(sym, size)
*/
#define ELF32_M_SYM(info) ((info)>>8)
#define ELF32_M_SIZE(info) ((unsigned char)(info))
#define ELF32_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
/*
* Hardware/Software capabilities entry
*/
typedef struct {
Elf32_Word c_tag; /* how to interpret value */
union {
Elf32_Word c_val;
Elf32_Addr c_ptr;
} c_un;
} Elf32_Cap;
/*
* Symbol table entries.
*/
typedef struct {
Elf32_Word st_name; /* String table index of name. */
Elf32_Addr st_value; /* Symbol value. */
Elf32_Word st_size; /* Size of associated object. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf32_Half st_shndx; /* Section index of symbol. */
} Elf32_Sym;
/* Macros for accessing the fields of st_info. */
#define ELF32_ST_BIND(info) ((info) >> 4)
#define ELF32_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
#define ELF32_ST_VISIBILITY(oth) ((oth) & 0x3)
/* Structures used by Sun & GNU symbol versioning. */
typedef struct
{
Elf32_Half vd_version;
Elf32_Half vd_flags;
Elf32_Half vd_ndx;
Elf32_Half vd_cnt;
Elf32_Word vd_hash;
Elf32_Word vd_aux;
Elf32_Word vd_next;
} Elf32_Verdef;
typedef struct
{
Elf32_Word vda_name;
Elf32_Word vda_next;
} Elf32_Verdaux;
typedef struct
{
Elf32_Half vn_version;
Elf32_Half vn_cnt;
Elf32_Word vn_file;
Elf32_Word vn_aux;
Elf32_Word vn_next;
} Elf32_Verneed;
typedef struct
{
Elf32_Word vna_hash;
Elf32_Half vna_flags;
Elf32_Half vna_other;
Elf32_Word vna_name;
Elf32_Word vna_next;
} Elf32_Vernaux;
typedef Elf32_Half Elf32_Versym;
typedef struct {
Elf32_Half si_boundto; /* direct bindings - symbol bound to */
Elf32_Half si_flags; /* per symbol flags */
} Elf32_Syminfo;
#endif /* !_SYS_ELF32_H_ */

View File

@ -1,248 +0,0 @@
/*-
* Copyright (c) 1996-1998 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/sys/elf64.h,v 1.17 2006/10/17 05:43:30 jkoshy Exp $
*/
#ifndef _SYS_ELF64_H_
#define _SYS_ELF64_H_ 1
#include <sys/elf_common.h>
/*
* ELF definitions common to all 64-bit architectures.
*/
typedef uint64_t Elf64_Addr;
typedef uint16_t Elf64_Half;
typedef uint64_t Elf64_Off;
typedef int32_t Elf64_Sword;
typedef int64_t Elf64_Sxword;
typedef uint32_t Elf64_Word;
typedef uint64_t Elf64_Lword;
typedef uint64_t Elf64_Xword;
/*
* Types of dynamic symbol hash table bucket and chain elements.
*
* This is inconsistent among 64 bit architectures, so a machine dependent
* typedef is required.
*/
typedef Elf64_Word Elf64_Hashelt;
/* Non-standard class-dependent datatype used for abstraction. */
typedef Elf64_Xword Elf64_Size;
typedef Elf64_Sxword Elf64_Ssize;
/*
* ELF header.
*/
typedef struct {
unsigned char e_ident[EI_NIDENT]; /* File identification. */
Elf64_Half e_type; /* File type. */
Elf64_Half e_machine; /* Machine architecture. */
Elf64_Word e_version; /* ELF format version. */
Elf64_Addr e_entry; /* Entry point. */
Elf64_Off e_phoff; /* Program header file offset. */
Elf64_Off e_shoff; /* Section header file offset. */
Elf64_Word e_flags; /* Architecture-specific flags. */
Elf64_Half e_ehsize; /* Size of ELF header in bytes. */
Elf64_Half e_phentsize; /* Size of program header entry. */
Elf64_Half e_phnum; /* Number of program header entries. */
Elf64_Half e_shentsize; /* Size of section header entry. */
Elf64_Half e_shnum; /* Number of section header entries. */
Elf64_Half e_shstrndx; /* Section name strings section. */
} Elf64_Ehdr;
/*
* Section header.
*/
typedef struct {
Elf64_Word sh_name; /* Section name (index into the
section header string table). */
Elf64_Word sh_type; /* Section type. */
Elf64_Xword sh_flags; /* Section flags. */
Elf64_Addr sh_addr; /* Address in memory image. */
Elf64_Off sh_offset; /* Offset in file. */
Elf64_Xword sh_size; /* Size in bytes. */
Elf64_Word sh_link; /* Index of a related section. */
Elf64_Word sh_info; /* Depends on section type. */
Elf64_Xword sh_addralign; /* Alignment in bytes. */
Elf64_Xword sh_entsize; /* Size of each entry in section. */
} Elf64_Shdr;
/*
* Program header.
*/
typedef struct {
Elf64_Word p_type; /* Entry type. */
Elf64_Word p_flags; /* Access permission flags. */
Elf64_Off p_offset; /* File offset of contents. */
Elf64_Addr p_vaddr; /* Virtual address in memory image. */
Elf64_Addr p_paddr; /* Physical address (not used). */
Elf64_Xword p_filesz; /* Size of contents in file. */
Elf64_Xword p_memsz; /* Size of contents in memory. */
Elf64_Xword p_align; /* Alignment in memory and file. */
} Elf64_Phdr;
/*
* Dynamic structure. The ".dynamic" section contains an array of them.
*/
typedef struct {
Elf64_Sxword d_tag; /* Entry type. */
union {
Elf64_Xword d_val; /* Integer value. */
Elf64_Addr d_ptr; /* Address value. */
} d_un;
} Elf64_Dyn;
/*
* Relocation entries.
*/
/* Relocations that don't need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
} Elf64_Rel;
/* Relocations that need an addend field. */
typedef struct {
Elf64_Addr r_offset; /* Location to be relocated. */
Elf64_Xword r_info; /* Relocation type and symbol index. */
Elf64_Sxword r_addend; /* Addend. */
} Elf64_Rela;
/* Macros for accessing the fields of r_info. */
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xffffffffL)
/* Macro for constructing r_info from field values. */
#define ELF64_R_INFO(sym, type) (((sym) << 32) + ((type) & 0xffffffffL))
#define ELF64_R_TYPE_DATA(info) (((Elf64_Xword)(info)<<32)>>40)
#define ELF64_R_TYPE_ID(info) (((Elf64_Xword)(info)<<56)>>56)
#define ELF64_R_TYPE_INFO(data, type) \
(((Elf64_Xword)(data)<<8)+(Elf64_Xword)(type))
/*
* Note entry header
*/
typedef Elf_Note Elf64_Nhdr;
/*
* Move entry
*/
typedef struct {
Elf64_Lword m_value; /* symbol value */
Elf64_Xword m_info; /* size + index */
Elf64_Xword m_poffset; /* symbol offset */
Elf64_Half m_repeat; /* repeat count */
Elf64_Half m_stride; /* stride info */
} Elf64_Move;
#define ELF64_M_SYM(info) ((info)>>8)
#define ELF64_M_SIZE(info) ((unsigned char)(info))
#define ELF64_M_INFO(sym, size) (((sym)<<8)+(unsigned char)(size))
/*
* Hardware/Software capabilities entry
*/
typedef struct {
Elf64_Xword c_tag; /* how to interpret value */
union {
Elf64_Xword c_val;
Elf64_Addr c_ptr;
} c_un;
} Elf64_Cap;
/*
* Symbol table entries.
*/
typedef struct {
Elf64_Word st_name; /* String table index of name. */
unsigned char st_info; /* Type and binding information. */
unsigned char st_other; /* Reserved (not used). */
Elf64_Half st_shndx; /* Section index of symbol. */
Elf64_Addr st_value; /* Symbol value. */
Elf64_Xword st_size; /* Size of associated object. */
} Elf64_Sym;
/* Macros for accessing the fields of st_info. */
#define ELF64_ST_BIND(info) ((info) >> 4)
#define ELF64_ST_TYPE(info) ((info) & 0xf)
/* Macro for constructing st_info from field values. */
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
/* Macro for accessing the fields of st_other. */
#define ELF64_ST_VISIBILITY(oth) ((oth) & 0x3)
/* Structures used by Sun & GNU-style symbol versioning. */
typedef struct {
Elf64_Half vd_version;
Elf64_Half vd_flags;
Elf64_Half vd_ndx;
Elf64_Half vd_cnt;
Elf64_Word vd_hash;
Elf64_Word vd_aux;
Elf64_Word vd_next;
} Elf64_Verdef;
typedef struct {
Elf64_Word vda_name;
Elf64_Word vda_next;
} Elf64_Verdaux;
typedef struct {
Elf64_Half vn_version;
Elf64_Half vn_cnt;
Elf64_Word vn_file;
Elf64_Word vn_aux;
Elf64_Word vn_next;
} Elf64_Verneed;
typedef struct {
Elf64_Word vna_hash;
Elf64_Half vna_flags;
Elf64_Half vna_other;
Elf64_Word vna_name;
Elf64_Word vna_next;
} Elf64_Vernaux;
typedef Elf64_Half Elf64_Versym;
typedef struct {
Elf64_Half si_boundto; /* direct bindings - symbol bound to */
Elf64_Half si_flags; /* per symbol flags */
} Elf64_Syminfo;
#endif /* !_SYS_ELF64_H_ */

View File

@ -1,865 +0,0 @@
/*-
* Copyright (c) 1998 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/sys/elf_common.h,v 1.24 2008/08/02 01:20:10 imp Exp $
*/
#ifndef _SYS_ELF_COMMON_H_
#define _SYS_ELF_COMMON_H_ 1
/*
* ELF definitions that are independent of architecture or word size.
*/
/*
* Note header. The ".note" section contains an array of notes. Each
* begins with this header, aligned to a word boundary. Immediately
* following the note header is n_namesz bytes of name, padded to the
* next word boundary. Then comes n_descsz bytes of descriptor, again
* padded to a word boundary. The values of n_namesz and n_descsz do
* not include the padding.
*/
typedef struct {
u_int32_t n_namesz; /* Length of name. */
u_int32_t n_descsz; /* Length of descriptor. */
u_int32_t n_type; /* Type of this note. */
} Elf_Note;
/* Indexes into the e_ident array. Keep synced with
http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
#define EI_MAG0 0 /* Magic number, byte 0. */
#define EI_MAG1 1 /* Magic number, byte 1. */
#define EI_MAG2 2 /* Magic number, byte 2. */
#define EI_MAG3 3 /* Magic number, byte 3. */
#define EI_CLASS 4 /* Class of machine. */
#define EI_DATA 5 /* Data format. */
#define EI_VERSION 6 /* ELF format version. */
#define EI_OSABI 7 /* Operating system / ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define OLD_EI_BRAND 8 /* Start of architecture identification. */
#define EI_PAD 9 /* Start of padding (per SVR4 ABI). */
#define EI_NIDENT 16 /* Size of e_ident array. */
/* Values for the magic number bytes. */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFMAG "\177ELF" /* magic string */
#define SELFMAG 4 /* magic string size */
/* Values for e_ident[EI_VERSION] and e_version. */
#define EV_NONE 0
#define EV_CURRENT 1
/* Values for e_ident[EI_CLASS]. */
#define ELFCLASSNONE 0 /* Unknown class. */
#define ELFCLASS32 1 /* 32-bit architecture. */
#define ELFCLASS64 2 /* 64-bit architecture. */
/* Values for e_ident[EI_DATA]. */
#define ELFDATANONE 0 /* Unknown data format. */
#define ELFDATA2LSB 1 /* 2's complement little-endian. */
#define ELFDATA2MSB 2 /* 2's complement big-endian. */
/* Values for e_ident[EI_OSABI]. */
#define ELFOSABI_NONE 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 common IA32 ABI */
#define ELFOSABI_SOLARIS 6 /* Solaris */
#define ELFOSABI_AIX 7 /* AIX */
#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 */
#define ELFOSABI_OPENVMS 13 /* Open VMS */
#define ELFOSABI_NSK 14 /* HP Non-Stop Kernel */
#define ELFOSABI_ARM 97 /* ARM */
#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
#define ELFOSABI_SYSV ELFOSABI_NONE /* symbol used in old spec */
#define ELFOSABI_MONTEREY ELFOSABI_AIX /* Monterey */
/* e_ident */
#define IS_ELF(ehdr) ((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
(ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
(ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
(ehdr).e_ident[EI_MAG3] == ELFMAG3)
/* Values for e_type. */
#define ET_NONE 0 /* Unknown type. */
#define ET_REL 1 /* Relocatable. */
#define ET_EXEC 2 /* Executable. */
#define ET_DYN 3 /* Shared object. */
#define ET_CORE 4 /* Core file. */
#define ET_LOOS 0xfe00 /* First operating system specific. */
#define ET_HIOS 0xfeff /* Last operating system-specific. */
#define ET_LOPROC 0xff00 /* First processor-specific. */
#define ET_HIPROC 0xffff /* Last processor-specific. */
/* Values for e_machine. */
#define EM_NONE 0 /* Unknown machine. */
#define EM_M32 1 /* AT&T WE32100. */
#define EM_SPARC 2 /* Sun SPARC. */
#define EM_386 3 /* Intel i386. */
#define EM_68K 4 /* Motorola 68000. */
#define EM_88K 5 /* Motorola 88000. */
#define EM_860 7 /* Intel i860. */
#define EM_MIPS 8 /* MIPS R3000 Big-Endian only. */
#define EM_S370 9 /* IBM System/370. */
#define EM_MIPS_RS3_LE 10 /* MIPS R3000 Little-Endian. */
#define EM_PARISC 15 /* HP PA-RISC. */
#define EM_VPP500 17 /* Fujitsu VPP500. */
#define EM_SPARC32PLUS 18 /* SPARC v8plus. */
#define EM_960 19 /* Intel 80960. */
#define EM_PPC 20 /* PowerPC 32-bit. */
#define EM_PPC64 21 /* PowerPC 64-bit. */
#define EM_S390 22 /* IBM System/390. */
#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 /* ARM. */
#define EM_SH 42 /* Hitachi SH. */
#define EM_SPARCV9 43 /* SPARC v9 64-bit. */
#define EM_TRICORE 44 /* Siemens TriCore embedded processor. */
#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 IA-64 Processor. */
#define EM_MIPS_X 51 /* Stanford MIPS-X. */
#define EM_COLDFIRE 52 /* Motorola ColdFire. */
#define EM_68HC12 53 /* Motorola M68HC12. */
#define EM_MMA 54 /* Fujitsu MMA. */
#define EM_PCP 55 /* Siemens PCP. */
#define EM_NCPU 56 /* Sony nCPU. */
#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 processor. */
#define EM_X86_64 62 /* Advanced Micro Devices x86-64 */
#define EM_AMD64 EM_X86_64 /* Advanced Micro Devices x86-64 (compat) */
/* Non-standard or deprecated. */
#define EM_486 6 /* Intel i486. */
#define EM_MIPS_RS4_BE 10 /* MIPS R4000 Big-Endian */
#define EM_ALPHA_STD 41 /* Digital Alpha (standard value). */
#define EM_ALPHA 0x9026 /* Alpha (written in the absence of an ABI) */
/* Special section indexes. */
#define SHN_UNDEF 0 /* Undefined, missing, irrelevant. */
#define SHN_LORESERVE 0xff00 /* First of reserved range. */
#define SHN_LOPROC 0xff00 /* First processor-specific. */
#define SHN_HIPROC 0xff1f /* Last processor-specific. */
#define SHN_LOOS 0xff20 /* First operating system-specific. */
#define SHN_HIOS 0xff3f /* Last operating system-specific. */
#define SHN_ABS 0xfff1 /* Absolute values. */
#define SHN_COMMON 0xfff2 /* Common data. */
#define SHN_XINDEX 0xffff /* Escape -- index stored elsewhere. */
#define SHN_HIRESERVE 0xffff /* Last of reserved range. */
/* sh_type */
#define SHT_NULL 0 /* inactive */
#define SHT_PROGBITS 1 /* program defined information */
#define SHT_SYMTAB 2 /* symbol table section */
#define SHT_STRTAB 3 /* string table section */
#define SHT_RELA 4 /* relocation section with addends */
#define SHT_HASH 5 /* symbol hash table section */
#define SHT_DYNAMIC 6 /* dynamic section */
#define SHT_NOTE 7 /* note section */
#define SHT_NOBITS 8 /* no space section */
#define SHT_REL 9 /* relocation section - no addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* Initialization function pointers. */
#define SHT_FINI_ARRAY 15 /* Termination function pointers. */
#define SHT_PREINIT_ARRAY 16 /* Pre-initialization function ptrs. */
#define SHT_GROUP 17 /* Section group. */
#define SHT_SYMTAB_SHNDX 18 /* Section indexes (see SHN_XINDEX). */
#define SHT_LOOS 0x60000000 /* First of OS specific semantics */
#define SHT_LOSUNW 0x6ffffff4
#define SHT_SUNW_dof 0x6ffffff4
#define SHT_SUNW_cap 0x6ffffff5
#define SHT_SUNW_SIGNATURE 0x6ffffff6
#define SHT_SUNW_ANNOTATE 0x6ffffff7
#define SHT_SUNW_DEBUGSTR 0x6ffffff8
#define SHT_SUNW_DEBUG 0x6ffffff9
#define SHT_SUNW_move 0x6ffffffa
#define SHT_SUNW_COMDAT 0x6ffffffb
#define SHT_SUNW_syminfo 0x6ffffffc
#define SHT_SUNW_verdef 0x6ffffffd
#define SHT_GNU_verdef 0x6ffffffd /* Symbol versions provided */
#define SHT_SUNW_verneed 0x6ffffffe
#define SHT_GNU_verneed 0x6ffffffe /* Symbol versions required */
#define SHT_SUNW_versym 0x6fffffff
#define SHT_GNU_versym 0x6fffffff /* Symbol version table */
#define SHT_HISUNW 0x6fffffff
#define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_AMD64_UNWIND 0x70000001 /* unwind information */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
/* Flags for sh_flags. */
#define SHF_WRITE 0x1 /* Section contains writable data. */
#define SHF_ALLOC 0x2 /* Section occupies memory. */
#define SHF_EXECINSTR 0x4 /* Section contains instructions. */
#define SHF_MERGE 0x10 /* Section may be merged. */
#define SHF_STRINGS 0x20 /* Section contains strings. */
#define SHF_INFO_LINK 0x40 /* sh_info holds section index. */
#define SHF_LINK_ORDER 0x80 /* Special ordering requirements. */
#define SHF_OS_NONCONFORMING 0x100 /* OS-specific processing required. */
#define SHF_GROUP 0x200 /* Member of section group. */
#define SHF_TLS 0x400 /* Section contains TLS data. */
#define SHF_MASKOS 0x0ff00000 /* OS-specific semantics. */
#define SHF_MASKPROC 0xf0000000 /* Processor-specific semantics. */
/* Values for p_type. */
#define PT_NULL 0 /* Unused entry. */
#define PT_LOAD 1 /* Loadable segment. */
#define PT_DYNAMIC 2 /* Dynamic linking information segment. */
#define PT_INTERP 3 /* Pathname of interpreter. */
#define PT_NOTE 4 /* Auxiliary information. */
#define PT_SHLIB 5 /* Reserved (not used). */
#define PT_PHDR 6 /* Location of program header itself. */
#define PT_TLS 7 /* Thread local storage segment */
#define PT_LOOS 0x60000000 /* First OS-specific. */
#define PT_SUNW_UNWIND 0x6464e550 /* amd64 UNWIND program header */
#define PT_GNU_EH_FRAME 0x6474e550
#define PT_LOSUNW 0x6ffffffa
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
#define PT_SUNWDTRACE 0x6ffffffc /* private */
#define PT_SUNWCAP 0x6ffffffd /* hard/soft capabilities segment */
#define PT_HISUNW 0x6fffffff
#define PT_HIOS 0x6fffffff /* Last OS-specific. */
#define PT_LOPROC 0x70000000 /* First processor-specific type. */
#define PT_HIPROC 0x7fffffff /* Last processor-specific type. */
/* Values for p_flags. */
#define PF_X 0x1 /* Executable. */
#define PF_W 0x2 /* Writable. */
#define PF_R 0x4 /* Readable. */
#define PF_MASKOS 0x0ff00000 /* Operating system-specific. */
#define PF_MASKPROC 0xf0000000 /* Processor-specific. */
/* Extended program header index. */
#define PN_XNUM 0xffff
/* Values for d_tag. */
#define DT_NULL 0 /* Terminating entry. */
#define DT_NEEDED 1 /* String table offset of a needed shared
library. */
#define DT_PLTRELSZ 2 /* Total size in bytes of PLT relocations. */
#define DT_PLTGOT 3 /* Processor-dependent address. */
#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 ElfNN_Rela relocations. */
#define DT_RELASZ 8 /* Total size of ElfNN_Rela relocations. */
#define DT_RELAENT 9 /* Size of each ElfNN_Rela relocation entry. */
#define DT_STRSZ 10 /* Size of string table. */
#define DT_SYMENT 11 /* Size of each symbol table entry. */
#define DT_INIT 12 /* Address of initialization function. */
#define DT_FINI 13 /* Address of finalization function. */
#define DT_SONAME 14 /* String table offset of shared object
name. */
#define DT_RPATH 15 /* String table offset of library path. [sup] */
#define DT_SYMBOLIC 16 /* Indicates "symbolic" linking. [sup] */
#define DT_REL 17 /* Address of ElfNN_Rel relocations. */
#define DT_RELSZ 18 /* Total size of ElfNN_Rel relocations. */
#define DT_RELENT 19 /* Size of each ElfNN_Rel relocation. */
#define DT_PLTREL 20 /* Type of relocation used for PLT. */
#define DT_DEBUG 21 /* Reserved (not used). */
#define DT_TEXTREL 22 /* Indicates there may be relocations in
non-writable segments. [sup] */
#define DT_JMPREL 23 /* Address of PLT relocations. */
#define DT_BIND_NOW 24 /* [sup] */
#define DT_INIT_ARRAY 25 /* Address of the array of pointers to
initialization functions */
#define DT_FINI_ARRAY 26 /* Address of the array of pointers to
termination functions */
#define DT_INIT_ARRAYSZ 27 /* Size in bytes of the array of
initialization functions. */
#define DT_FINI_ARRAYSZ 28 /* Size in bytes of the array of
terminationfunctions. */
#define DT_RUNPATH 29 /* String table offset of a null-terminated
library search path string. */
#define DT_FLAGS 30 /* Object specific flag values. */
#define DT_ENCODING 32 /* Values greater than or equal to DT_ENCODING
and less than DT_LOOS follow the rules for
the interpretation of the d_un union
as follows: even == 'd_ptr', even == 'd_val'
or none */
#define DT_PREINIT_ARRAY 32 /* Address of the array of pointers to
pre-initialization functions. */
#define DT_PREINIT_ARRAYSZ 33 /* Size in bytes of the array of
pre-initialization functions. */
#define DT_MAXPOSTAGS 34 /* number of positive tags */
#define DT_LOOS 0x6000000d /* First OS-specific */
#define DT_SUNW_AUXILIARY 0x6000000d /* symbol auxiliary name */
#define DT_SUNW_RTLDINF 0x6000000e /* ld.so.1 info (private) */
#define DT_SUNW_FILTER 0x6000000f /* symbol filter name */
#define DT_SUNW_CAP 0x60000010 /* hardware/software */
#define DT_HIOS 0x6ffff000 /* Last OS-specific */
/*
* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
* Dyn.d_un.d_val field of the Elf*_Dyn structure.
*/
#define DT_VALRNGLO 0x6ffffd00
#define DT_CHECKSUM 0x6ffffdf8 /* elf checksum */
#define DT_PLTPADSZ 0x6ffffdf9 /* pltpadding size */
#define DT_MOVEENT 0x6ffffdfa /* move table entry size */
#define DT_MOVESZ 0x6ffffdfb /* move table size */
#define DT_FEATURE_1 0x6ffffdfc /* feature holder */
#define DT_POSFLAG_1 0x6ffffdfd /* flags for DT_* entries, effecting */
/* the following DT_* entry. */
/* See DF_P1_* definitions */
#define DT_SYMINSZ 0x6ffffdfe /* syminfo table size (in bytes) */
#define DT_SYMINENT 0x6ffffdff /* syminfo entry size (in bytes) */
#define DT_VALRNGHI 0x6ffffdff
/*
* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
* Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
*
* If any adjustment is made to the ELF object after it has been
* built, these entries will need to be adjusted.
*/
#define DT_ADDRRNGLO 0x6ffffe00
#define DT_CONFIG 0x6ffffefa /* configuration information */
#define DT_DEPAUDIT 0x6ffffefb /* dependency auditing */
#define DT_AUDIT 0x6ffffefc /* object auditing */
#define DT_PLTPAD 0x6ffffefd /* pltpadding (sparcv9) */
#define DT_MOVETAB 0x6ffffefe /* move table */
#define DT_SYMINFO 0x6ffffeff /* syminfo table */
#define DT_ADDRRNGHI 0x6ffffeff
#define DT_VERSYM 0x6ffffff0 /* Address of versym section. */
#define DT_RELACOUNT 0x6ffffff9 /* number of RELATIVE relocations */
#define DT_RELCOUNT 0x6ffffffa /* number of RELATIVE relocations */
#define DT_FLAGS_1 0x6ffffffb /* state flags - see DF_1_* defs */
#define DT_VERDEF 0x6ffffffc /* Address of verdef section. */
#define DT_VERDEFNUM 0x6ffffffd /* Number of elems in verdef section */
#define DT_VERNEED 0x6ffffffe /* Address of verneed section. */
#define DT_VERNEEDNUM 0x6fffffff /* Number of elems in verneed section */
#define DT_LOPROC 0x70000000 /* First processor-specific type. */
#define DT_DEPRECATED_SPARC_REGISTER 0x7000001
#define DT_AUXILIARY 0x7ffffffd /* shared library auxiliary name */
#define DT_USED 0x7ffffffe /* ignored - same as needed */
#define DT_FILTER 0x7fffffff /* shared library filter name */
#define DT_HIPROC 0x7fffffff /* Last processor-specific type. */
/* Values for DT_FLAGS */
#define DF_ORIGIN 0x0001 /* Indicates that the object being loaded may
make reference to the $ORIGIN substitution
string */
#define DF_SYMBOLIC 0x0002 /* Indicates "symbolic" linking. */
#define DF_TEXTREL 0x0004 /* Indicates there may be relocations in
non-writable segments. */
#define DF_BIND_NOW 0x0008 /* Indicates that the dynamic linker should
process all relocations for the object
containing this entry before transferring
control to the program. */
#define DF_STATIC_TLS 0x0010 /* Indicates that the shared object or
executable contains code using a static
thread-local storage scheme. */
/* Values for n_type. Used in core files. */
#define NT_PRSTATUS 1 /* Process status. */
#define NT_FPREGSET 2 /* Floating point registers. */
#define NT_PRPSINFO 3 /* Process state info. */
/* Symbol Binding - ELFNN_ST_BIND - st_info */
#define STB_LOCAL 0 /* Local symbol */
#define STB_GLOBAL 1 /* Global symbol */
#define STB_WEAK 2 /* like global - lower precedence */
#define STB_LOOS 10 /* Reserved range for operating system */
#define STB_HIOS 12 /* specific semantics. */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific semantics. */
/* Symbol type - ELFNN_ST_TYPE - st_info */
#define STT_NOTYPE 0 /* Unspecified type. */
#define STT_OBJECT 1 /* Data object. */
#define STT_FUNC 2 /* Function. */
#define STT_SECTION 3 /* Section. */
#define STT_FILE 4 /* Source file. */
#define STT_COMMON 5 /* Uninitialized common block. */
#define STT_TLS 6 /* TLS object. */
#define STT_NUM 7
#define STT_LOOS 10 /* Reserved range for operating system */
#define STT_HIOS 12 /* specific semantics. */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific semantics. */
/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
#define STV_DEFAULT 0x0 /* Default visibility (see binding). */
#define STV_INTERNAL 0x1 /* Special meaning in relocatable objects. */
#define STV_HIDDEN 0x2 /* Not visible. */
#define STV_PROTECTED 0x3 /* Visible but not preemptible. */
#define STV_EXPORTED 0x4
#define STV_SINGLETON 0x5
#define STV_ELIMINATE 0x6
/* Special symbol table indexes. */
#define STN_UNDEF 0 /* Undefined symbol index. */
/* Symbol versioning flags. */
#define VER_DEF_CURRENT 1
#define VER_DEF_IDX(x) VER_NDX(x)
#define VER_FLG_BASE 0x01
#define VER_FLG_WEAK 0x02
#define VER_NEED_CURRENT 1
#define VER_NEED_WEAK (1u << 15)
#define VER_NEED_HIDDEN VER_NDX_HIDDEN
#define VER_NEED_IDX(x) VER_NDX(x)
#define VER_NDX_LOCAL 0
#define VER_NDX_GLOBAL 1
#define VER_NDX_GIVEN 2
#define VER_NDX_HIDDEN (1u << 15)
#define VER_NDX(x) ((x) & ~(1u << 15))
#define CA_SUNW_NULL 0
#define CA_SUNW_HW_1 1 /* first hardware capabilities entry */
#define CA_SUNW_SF_1 2 /* first software capabilities entry */
/*
* Syminfo flag values
*/
#define SYMINFO_FLG_DIRECT 0x0001 /* symbol ref has direct association */
/* to object containing defn. */
#define SYMINFO_FLG_PASSTHRU 0x0002 /* ignored - see SYMINFO_FLG_FILTER */
#define SYMINFO_FLG_COPY 0x0004 /* symbol is a copy-reloc */
#define SYMINFO_FLG_LAZYLOAD 0x0008 /* object containing defn should be */
/* lazily-loaded */
#define SYMINFO_FLG_DIRECTBIND 0x0010 /* ref should be bound directly to */
/* object containing defn. */
#define SYMINFO_FLG_NOEXTDIRECT 0x0020 /* don't let an external reference */
/* directly bind to this symbol */
#define SYMINFO_FLG_FILTER 0x0002 /* symbol ref is associated to a */
#define SYMINFO_FLG_AUXILIARY 0x0040 /* standard or auxiliary filter */
/*
* Syminfo.si_boundto values.
*/
#define SYMINFO_BT_SELF 0xffff /* symbol bound to self */
#define SYMINFO_BT_PARENT 0xfffe /* symbol bound to parent */
#define SYMINFO_BT_NONE 0xfffd /* no special symbol binding */
#define SYMINFO_BT_EXTERN 0xfffc /* symbol defined as external */
#define SYMINFO_BT_LOWRESERVE 0xff00 /* beginning of reserved entries */
/*
* Syminfo version values.
*/
#define SYMINFO_NONE 0 /* Syminfo version */
#define SYMINFO_CURRENT 1
#define SYMINFO_NUM 2
/*
* Relocation types.
*
* All machine architectures are defined here to allow tools on one to
* handle others.
*/
#define R_386_NONE 0 /* No relocation. */
#define R_386_32 1 /* Add symbol value. */
#define R_386_PC32 2 /* Add PC-relative symbol value. */
#define R_386_GOT32 3 /* Add PC-relative GOT offset. */
#define R_386_PLT32 4 /* Add PC-relative PLT offset. */
#define R_386_COPY 5 /* Copy data from shared object. */
#define R_386_GLOB_DAT 6 /* Set GOT entry to data address. */
#define R_386_JMP_SLOT 7 /* Set GOT entry to code address. */
#define R_386_RELATIVE 8 /* Add load address of shared object. */
#define R_386_GOTOFF 9 /* Add GOT-relative symbol address. */
#define R_386_GOTPC 10 /* Add PC-relative GOT table address. */
#define R_386_TLS_TPOFF 14 /* Negative offset in static TLS block */
#define R_386_TLS_IE 15 /* Absolute address of GOT for -ve static TLS */
#define R_386_TLS_GOTIE 16 /* GOT entry for negative static TLS block */
#define R_386_TLS_LE 17 /* Negative offset relative to static TLS */
#define R_386_TLS_GD 18 /* 32 bit offset to GOT (index,off) pair */
#define R_386_TLS_LDM 19 /* 32 bit offset to GOT (index,zero) pair */
#define R_386_TLS_GD_32 24 /* 32 bit offset to GOT (index,off) pair */
#define R_386_TLS_GD_PUSH 25 /* pushl instruction for Sun ABI GD sequence */
#define R_386_TLS_GD_CALL 26 /* call instruction for Sun ABI GD sequence */
#define R_386_TLS_GD_POP 27 /* popl instruction for Sun ABI GD sequence */
#define R_386_TLS_LDM_32 28 /* 32 bit offset to GOT (index,zero) pair */
#define R_386_TLS_LDM_PUSH 29 /* pushl instruction for Sun ABI LD sequence */
#define R_386_TLS_LDM_CALL 30 /* call instruction for Sun ABI LD sequence */
#define R_386_TLS_LDM_POP 31 /* popl instruction for Sun ABI LD sequence */
#define R_386_TLS_LDO_32 32 /* 32 bit offset from start of TLS block */
#define R_386_TLS_IE_32 33 /* 32 bit offset to GOT static TLS offset entry */
#define R_386_TLS_LE_32 34 /* 32 bit offset within static TLS block */
#define R_386_TLS_DTPMOD32 35 /* GOT entry containing TLS index */
#define R_386_TLS_DTPOFF32 36 /* GOT entry containing TLS offset */
#define R_386_TLS_TPOFF32 37 /* GOT entry of -ve static TLS offset */
#define R_ARM_NONE 0 /* No relocation. */
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
#define R_ARM_REL32 3
#define R_ARM_PC13 4
#define R_ARM_ABS16 5
#define R_ARM_ABS12 6
#define R_ARM_THM_ABS5 7
#define R_ARM_ABS8 8
#define R_ARM_SBREL32 9
#define R_ARM_THM_PC22 10
#define R_ARM_THM_PC8 11
#define R_ARM_AMP_VCALL9 12
#define R_ARM_SWI24 13
#define R_ARM_THM_SWI8 14
#define R_ARM_XPC25 15
#define R_ARM_THM_XPC22 16
#define R_ARM_TLS_DTPMOD32 17
#define R_ARM_COPY 20 /* Copy data from shared object. */
#define R_ARM_GLOB_DAT 21 /* Set GOT entry to data address. */
#define R_ARM_JUMP_SLOT 22 /* Set GOT entry to code address. */
#define R_ARM_RELATIVE 23 /* Add load address of shared object. */
#define R_ARM_GOTOFF 24 /* Add GOT-relative symbol address. */
#define R_ARM_GOTPC 25 /* Add PC-relative GOT table address. */
#define R_ARM_GOT32 26 /* Add PC-relative GOT offset. */
#define R_ARM_PLT32 27 /* Add PC-relative PLT offset. */
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
#define R_ARM_RSBREL32 250
#define R_ARM_THM_RPC22 251
#define R_ARM_RREL32 252
#define R_ARM_RABS32 253
#define R_ARM_RPC24 254
#define R_ARM_RBASE 255
/* Name Value Field Calculation */
#define R_IA_64_NONE 0 /* None */
#define R_IA_64_IMM14 0x21 /* immediate14 S + A */
#define R_IA_64_IMM22 0x22 /* immediate22 S + A */
#define R_IA_64_IMM64 0x23 /* immediate64 S + A */
#define R_IA_64_DIR32MSB 0x24 /* word32 MSB S + A */
#define R_IA_64_DIR32LSB 0x25 /* word32 LSB S + A */
#define R_IA_64_DIR64MSB 0x26 /* word64 MSB S + A */
#define R_IA_64_DIR64LSB 0x27 /* word64 LSB S + A */
#define R_IA_64_GPREL22 0x2a /* immediate22 @gprel(S + A) */
#define R_IA_64_GPREL64I 0x2b /* immediate64 @gprel(S + A) */
#define R_IA_64_GPREL32MSB 0x2c /* word32 MSB @gprel(S + A) */
#define R_IA_64_GPREL32LSB 0x2d /* word32 LSB @gprel(S + A) */
#define R_IA_64_GPREL64MSB 0x2e /* word64 MSB @gprel(S + A) */
#define R_IA_64_GPREL64LSB 0x2f /* word64 LSB @gprel(S + A) */
#define R_IA_64_LTOFF22 0x32 /* immediate22 @ltoff(S + A) */
#define R_IA_64_LTOFF64I 0x33 /* immediate64 @ltoff(S + A) */
#define R_IA_64_PLTOFF22 0x3a /* immediate22 @pltoff(S + A) */
#define R_IA_64_PLTOFF64I 0x3b /* immediate64 @pltoff(S + A) */
#define R_IA_64_PLTOFF64MSB 0x3e /* word64 MSB @pltoff(S + A) */
#define R_IA_64_PLTOFF64LSB 0x3f /* word64 LSB @pltoff(S + A) */
#define R_IA_64_FPTR64I 0x43 /* immediate64 @fptr(S + A) */
#define R_IA_64_FPTR32MSB 0x44 /* word32 MSB @fptr(S + A) */
#define R_IA_64_FPTR32LSB 0x45 /* word32 LSB @fptr(S + A) */
#define R_IA_64_FPTR64MSB 0x46 /* word64 MSB @fptr(S + A) */
#define R_IA_64_FPTR64LSB 0x47 /* word64 LSB @fptr(S + A) */
#define R_IA_64_PCREL60B 0x48 /* immediate60 form1 S + A - P */
#define R_IA_64_PCREL21B 0x49 /* immediate21 form1 S + A - P */
#define R_IA_64_PCREL21M 0x4a /* immediate21 form2 S + A - P */
#define R_IA_64_PCREL21F 0x4b /* immediate21 form3 S + A - P */
#define R_IA_64_PCREL32MSB 0x4c /* word32 MSB S + A - P */
#define R_IA_64_PCREL32LSB 0x4d /* word32 LSB S + A - P */
#define R_IA_64_PCREL64MSB 0x4e /* word64 MSB S + A - P */
#define R_IA_64_PCREL64LSB 0x4f /* word64 LSB S + A - P */
#define R_IA_64_LTOFF_FPTR22 0x52 /* immediate22 @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64I 0x53 /* immediate64 @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR32MSB 0x54 /* word32 MSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR32LSB 0x55 /* word32 LSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64MSB 0x56 /* word64 MSB @ltoff(@fptr(S + A)) */
#define R_IA_64_LTOFF_FPTR64LSB 0x57 /* word64 LSB @ltoff(@fptr(S + A)) */
#define R_IA_64_SEGREL32MSB 0x5c /* word32 MSB @segrel(S + A) */
#define R_IA_64_SEGREL32LSB 0x5d /* word32 LSB @segrel(S + A) */
#define R_IA_64_SEGREL64MSB 0x5e /* word64 MSB @segrel(S + A) */
#define R_IA_64_SEGREL64LSB 0x5f /* word64 LSB @segrel(S + A) */
#define R_IA_64_SECREL32MSB 0x64 /* word32 MSB @secrel(S + A) */
#define R_IA_64_SECREL32LSB 0x65 /* word32 LSB @secrel(S + A) */
#define R_IA_64_SECREL64MSB 0x66 /* word64 MSB @secrel(S + A) */
#define R_IA_64_SECREL64LSB 0x67 /* word64 LSB @secrel(S + A) */
#define R_IA_64_REL32MSB 0x6c /* word32 MSB BD + A */
#define R_IA_64_REL32LSB 0x6d /* word32 LSB BD + A */
#define R_IA_64_REL64MSB 0x6e /* word64 MSB BD + A */
#define R_IA_64_REL64LSB 0x6f /* word64 LSB BD + A */
#define R_IA_64_LTV32MSB 0x74 /* word32 MSB S + A */
#define R_IA_64_LTV32LSB 0x75 /* word32 LSB S + A */
#define R_IA_64_LTV64MSB 0x76 /* word64 MSB S + A */
#define R_IA_64_LTV64LSB 0x77 /* word64 LSB S + A */
#define R_IA_64_PCREL21BI 0x79 /* immediate21 form1 S + A - P */
#define R_IA_64_PCREL22 0x7a /* immediate22 S + A - P */
#define R_IA_64_PCREL64I 0x7b /* immediate64 S + A - P */
#define R_IA_64_IPLTMSB 0x80 /* function descriptor MSB special */
#define R_IA_64_IPLTLSB 0x81 /* function descriptor LSB speciaal */
#define R_IA_64_SUB 0x85 /* immediate64 A - S */
#define R_IA_64_LTOFF22X 0x86 /* immediate22 special */
#define R_IA_64_LDXMOV 0x87 /* immediate22 special */
#define R_IA_64_TPREL14 0x91 /* imm14 @tprel(S + A) */
#define R_IA_64_TPREL22 0x92 /* imm22 @tprel(S + A) */
#define R_IA_64_TPREL64I 0x93 /* imm64 @tprel(S + A) */
#define R_IA_64_TPREL64MSB 0x96 /* word64 MSB @tprel(S + A) */
#define R_IA_64_TPREL64LSB 0x97 /* word64 LSB @tprel(S + A) */
#define R_IA_64_LTOFF_TPREL22 0x9a /* imm22 @ltoff(@tprel(S+A)) */
#define R_IA_64_DTPMOD64MSB 0xa6 /* word64 MSB @dtpmod(S + A) */
#define R_IA_64_DTPMOD64LSB 0xa7 /* word64 LSB @dtpmod(S + A) */
#define R_IA_64_LTOFF_DTPMOD22 0xaa /* imm22 @ltoff(@dtpmod(S+A)) */
#define R_IA_64_DTPREL14 0xb1 /* imm14 @dtprel(S + A) */
#define R_IA_64_DTPREL22 0xb2 /* imm22 @dtprel(S + A) */
#define R_IA_64_DTPREL64I 0xb3 /* imm64 @dtprel(S + A) */
#define R_IA_64_DTPREL32MSB 0xb4 /* word32 MSB @dtprel(S + A) */
#define R_IA_64_DTPREL32LSB 0xb5 /* word32 LSB @dtprel(S + A) */
#define R_IA_64_DTPREL64MSB 0xb6 /* word64 MSB @dtprel(S + A) */
#define R_IA_64_DTPREL64LSB 0xb7 /* word64 LSB @dtprel(S + A) */
#define R_IA_64_LTOFF_DTPREL22 0xba /* imm22 @ltoff(@dtprel(S+A)) */
#define R_MIPS_NONE 0 /* No reloc */
#define R_MIPS_16 1 /* Direct 16 bit */
#define R_MIPS_32 2 /* Direct 32 bit */
#define R_MIPS_REL32 3 /* PC relative 32 bit */
#define R_MIPS_26 4 /* Direct 26 bit shifted */
#define R_MIPS_HI16 5 /* High 16 bit */
#define R_MIPS_LO16 6 /* Low 16 bit */
#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
#define R_MIPS_PC16 10 /* PC relative 16 bit */
#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
#define R_MIPS_GOTHI16 21 /* GOT HI 16 bit */
#define R_MIPS_GOTLO16 22 /* GOT LO 16 bit */
#define R_MIPS_CALLHI16 30 /* upper 16 bit GOT entry for function */
#define R_MIPS_CALLLO16 31 /* lower 16 bit GOT entry for function */
#define R_PPC_NONE 0 /* No relocation. */
#define R_PPC_ADDR32 1
#define R_PPC_ADDR24 2
#define R_PPC_ADDR16 3
#define R_PPC_ADDR16_LO 4
#define R_PPC_ADDR16_HI 5
#define R_PPC_ADDR16_HA 6
#define R_PPC_ADDR14 7
#define R_PPC_ADDR14_BRTAKEN 8
#define R_PPC_ADDR14_BRNTAKEN 9
#define R_PPC_REL24 10
#define R_PPC_REL14 11
#define R_PPC_REL14_BRTAKEN 12
#define R_PPC_REL14_BRNTAKEN 13
#define R_PPC_GOT16 14
#define R_PPC_GOT16_LO 15
#define R_PPC_GOT16_HI 16
#define R_PPC_GOT16_HA 17
#define R_PPC_PLTREL24 18
#define R_PPC_COPY 19
#define R_PPC_GLOB_DAT 20
#define R_PPC_JMP_SLOT 21
#define R_PPC_RELATIVE 22
#define R_PPC_LOCAL24PC 23
#define R_PPC_UADDR32 24
#define R_PPC_UADDR16 25
#define R_PPC_REL32 26
#define R_PPC_PLT32 27
#define R_PPC_PLTREL32 28
#define R_PPC_PLT16_LO 29
#define R_PPC_PLT16_HI 30
#define R_PPC_PLT16_HA 31
#define R_PPC_SDAREL16 32
#define R_PPC_SECTOFF 33
#define R_PPC_SECTOFF_LO 34
#define R_PPC_SECTOFF_HI 35
#define R_PPC_SECTOFF_HA 36
/*
* TLS relocations
*/
#define R_PPC_TLS 67
#define R_PPC_DTPMOD32 68
#define R_PPC_TPREL16 69
#define R_PPC_TPREL16_LO 70
#define R_PPC_TPREL16_HI 71
#define R_PPC_TPREL16_HA 72
#define R_PPC_TPREL32 73
#define R_PPC_DTPREL16 74
#define R_PPC_DTPREL16_LO 75
#define R_PPC_DTPREL16_HI 76
#define R_PPC_DTPREL16_HA 77
#define R_PPC_DTPREL32 78
#define R_PPC_GOT_TLSGD16 79
#define R_PPC_GOT_TLSGD16_LO 80
#define R_PPC_GOT_TLSGD16_HI 81
#define R_PPC_GOT_TLSGD16_HA 82
#define R_PPC_GOT_TLSLD16 83
#define R_PPC_GOT_TLSLD16_LO 84
#define R_PPC_GOT_TLSLD16_HI 85
#define R_PPC_GOT_TLSLD16_HA 86
#define R_PPC_GOT_TPREL16 87
#define R_PPC_GOT_TPREL16_LO 88
#define R_PPC_GOT_TPREL16_HI 89
#define R_PPC_GOT_TPREL16_HA 90
/*
* The remaining relocs are from the Embedded ELF ABI, and are not in the
* SVR4 ELF ABI.
*/
#define R_PPC_EMB_NADDR32 101
#define R_PPC_EMB_NADDR16 102
#define R_PPC_EMB_NADDR16_LO 103
#define R_PPC_EMB_NADDR16_HI 104
#define R_PPC_EMB_NADDR16_HA 105
#define R_PPC_EMB_SDAI16 106
#define R_PPC_EMB_SDA2I16 107
#define R_PPC_EMB_SDA2REL 108
#define R_PPC_EMB_SDA21 109
#define R_PPC_EMB_MRKREF 110
#define R_PPC_EMB_RELSEC16 111
#define R_PPC_EMB_RELST_LO 112
#define R_PPC_EMB_RELST_HI 113
#define R_PPC_EMB_RELST_HA 114
#define R_PPC_EMB_BIT_FLD 115
#define R_PPC_EMB_RELSDA 116
#define R_SPARC_NONE 0
#define R_SPARC_8 1
#define R_SPARC_16 2
#define R_SPARC_32 3
#define R_SPARC_DISP8 4
#define R_SPARC_DISP16 5
#define R_SPARC_DISP32 6
#define R_SPARC_WDISP30 7
#define R_SPARC_WDISP22 8
#define R_SPARC_HI22 9
#define R_SPARC_22 10
#define R_SPARC_13 11
#define R_SPARC_LO10 12
#define R_SPARC_GOT10 13
#define R_SPARC_GOT13 14
#define R_SPARC_GOT22 15
#define R_SPARC_PC10 16
#define R_SPARC_PC22 17
#define R_SPARC_WPLT30 18
#define R_SPARC_COPY 19
#define R_SPARC_GLOB_DAT 20
#define R_SPARC_JMP_SLOT 21
#define R_SPARC_RELATIVE 22
#define R_SPARC_UA32 23
#define R_SPARC_PLT32 24
#define R_SPARC_HIPLT22 25
#define R_SPARC_LOPLT10 26
#define R_SPARC_PCPLT32 27
#define R_SPARC_PCPLT22 28
#define R_SPARC_PCPLT10 29
#define R_SPARC_10 30
#define R_SPARC_11 31
#define R_SPARC_64 32
#define R_SPARC_OLO10 33
#define R_SPARC_HH22 34
#define R_SPARC_HM10 35
#define R_SPARC_LM22 36
#define R_SPARC_PC_HH22 37
#define R_SPARC_PC_HM10 38
#define R_SPARC_PC_LM22 39
#define R_SPARC_WDISP16 40
#define R_SPARC_WDISP19 41
#define R_SPARC_GLOB_JMP 42
#define R_SPARC_7 43
#define R_SPARC_5 44
#define R_SPARC_6 45
#define R_SPARC_DISP64 46
#define R_SPARC_PLT64 47
#define R_SPARC_HIX22 48
#define R_SPARC_LOX10 49
#define R_SPARC_H44 50
#define R_SPARC_M44 51
#define R_SPARC_L44 52
#define R_SPARC_REGISTER 53
#define R_SPARC_UA64 54
#define R_SPARC_UA16 55
#define R_SPARC_TLS_GD_HI22 56
#define R_SPARC_TLS_GD_LO10 57
#define R_SPARC_TLS_GD_ADD 58
#define R_SPARC_TLS_GD_CALL 59
#define R_SPARC_TLS_LDM_HI22 60
#define R_SPARC_TLS_LDM_LO10 61
#define R_SPARC_TLS_LDM_ADD 62
#define R_SPARC_TLS_LDM_CALL 63
#define R_SPARC_TLS_LDO_HIX22 64
#define R_SPARC_TLS_LDO_LOX10 65
#define R_SPARC_TLS_LDO_ADD 66
#define R_SPARC_TLS_IE_HI22 67
#define R_SPARC_TLS_IE_LO10 68
#define R_SPARC_TLS_IE_LD 69
#define R_SPARC_TLS_IE_LDX 70
#define R_SPARC_TLS_IE_ADD 71
#define R_SPARC_TLS_LE_HIX22 72
#define R_SPARC_TLS_LE_LOX10 73
#define R_SPARC_TLS_DTPMOD32 74
#define R_SPARC_TLS_DTPMOD64 75
#define R_SPARC_TLS_DTPOFF32 76
#define R_SPARC_TLS_DTPOFF64 77
#define R_SPARC_TLS_TPOFF32 78
#define R_SPARC_TLS_TPOFF64 79
#define R_X86_64_NONE 0 /* No relocation. */
#define R_X86_64_64 1 /* Add 64 bit symbol value. */
#define R_X86_64_PC32 2 /* PC-relative 32 bit signed sym value. */
#define R_X86_64_GOT32 3 /* PC-relative 32 bit GOT offset. */
#define R_X86_64_PLT32 4 /* PC-relative 32 bit PLT offset. */
#define R_X86_64_COPY 5 /* Copy data from shared object. */
#define R_X86_64_GLOB_DAT 6 /* Set GOT entry to data address. */
#define R_X86_64_JMP_SLOT 7 /* Set GOT entry to code address. */
#define R_X86_64_RELATIVE 8 /* Add load address of shared object. */
#define R_X86_64_GOTPCREL 9 /* Add 32 bit signed pcrel offset to GOT. */
#define R_X86_64_32 10 /* Add 32 bit zero extended symbol value */
#define R_X86_64_32S 11 /* Add 32 bit sign extended symbol value */
#define R_X86_64_16 12 /* Add 16 bit zero extended symbol value */
#define R_X86_64_PC16 13 /* Add 16 bit signed extended pc relative symbol value */
#define R_X86_64_8 14 /* Add 8 bit zero extended symbol value */
#define R_X86_64_PC8 15 /* Add 8 bit signed extended pc relative symbol value */
#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
#define R_X86_64_DTPOFF64 17 /* Offset in TLS block */
#define R_X86_64_TPOFF64 18 /* Offset in static TLS block */
#define R_X86_64_TLSGD 19 /* PC relative offset to GD GOT entry */
#define R_X86_64_TLSLD 20 /* PC relative offset to LD GOT entry */
#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
#define R_X86_64_GOTTPOFF 22 /* PC relative offset to IE GOT entry */
#define R_X86_64_TPOFF32 23 /* Offset in static TLS block */
#endif /* !_SYS_ELF_COMMON_H_ */

View File

@ -1,88 +0,0 @@
/*-
* Copyright (c) 1998 John D. Polstra.
* All rights reserved.
*
* 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 AUTHOR 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 AUTHOR 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.
*
* $FreeBSD: src/sys/sys/elf_generic.h,v 1.8 2005/12/18 19:43:33 kan Exp $
*/
#ifndef _SYS_ELF_GENERIC_H_
#define _SYS_ELF_GENERIC_H_ 1
#include <sys/cdefs.h>
/*
* Definitions of generic ELF names which relieve applications from
* needing to know the word size.
*/
#if __ELF_WORD_SIZE != 32 && __ELF_WORD_SIZE != 64
#error "__ELF_WORD_SIZE must be defined as 32 or 64"
#endif
#define ELF_CLASS __CONCAT(ELFCLASS,__ELF_WORD_SIZE)
#if BYTE_ORDER == LITTLE_ENDIAN
#define ELF_DATA ELFDATA2LSB
#elif BYTE_ORDER == BIG_ENDIAN
#define ELF_DATA ELFDATA2MSB
#else
#error "Unknown byte order"
#endif
#define __elfN(x) __CONCAT(__CONCAT(__CONCAT(elf,__ELF_WORD_SIZE),_),x)
#define __ElfN(x) __CONCAT(__CONCAT(__CONCAT(Elf,__ELF_WORD_SIZE),_),x)
#define __ELFN(x) __CONCAT(__CONCAT(__CONCAT(ELF,__ELF_WORD_SIZE),_),x)
#define __ElfType(x) typedef __ElfN(x) __CONCAT(Elf_,x)
__ElfType(Addr);
__ElfType(Half);
__ElfType(Off);
__ElfType(Sword);
__ElfType(Word);
__ElfType(Ehdr);
__ElfType(Shdr);
__ElfType(Phdr);
__ElfType(Dyn);
__ElfType(Rel);
__ElfType(Rela);
__ElfType(Sym);
__ElfType(Verdef);
__ElfType(Verdaux);
__ElfType(Verneed);
__ElfType(Vernaux);
__ElfType(Versym);
/* Non-standard ELF types. */
__ElfType(Hashelt);
__ElfType(Size);
__ElfType(Ssize);
#define ELF_R_SYM __ELFN(R_SYM)
#define ELF_R_TYPE __ELFN(R_TYPE)
#define ELF_R_INFO __ELFN(R_INFO)
#define ELF_ST_BIND __ELFN(ST_BIND)
#define ELF_ST_TYPE __ELFN(ST_TYPE)
#define ELF_ST_INFO __ELFN(ST_INFO)
#endif /* !_SYS_ELF_GENERIC_H_ */

View File

@ -1,99 +0,0 @@
/*-
* Copyright (c) 1993 Paul Kranenburg
* All rights reserved.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Paul Kranenburg.
* 4. 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.
*
* $FreeBSD: src/sys/sys/link_elf.h,v 1.29 2008/07/11 01:10:40 obrien Exp $
*/
/*
* RRS section definitions.
*
* The layout of some data structures defined in this header file is
* such that we can provide compatibility with the SunOS 4.x shared
* library scheme.
*/
#ifndef _SYS_LINK_ELF_H_
#define _SYS_LINK_ELF_H_
#include <sys/elf.h>
/*
* Flags that describe the origin of the entries in Dl_serinfo.
* SunOS has these in <sys/link.h>, we follow the suit.
*/
#define LA_SER_ORIG 0x01 /* original (needed) name */
#define LA_SER_LIBPATH 0x02 /* LD_LIBRARY_PATH entry prepended */
#define LA_SER_RUNPATH 0x04 /* runpath entry prepended */
#define LA_SER_CONFIG 0x08 /* configuration entry prepended */
#define LA_SER_DEFAULT 0x40 /* default path prepended */
#define LA_SER_SECURE 0x80 /* default (secure) path prepended */
typedef struct link_map {
caddr_t l_addr; /* Base Address of library */
#ifdef __mips__
caddr_t l_offs; /* Load Offset of library */
#endif
const char *l_name; /* Absolute Path to Library */
const void *l_ld; /* Pointer to .dynamic in memory */
struct link_map *l_next, *l_prev; /* linked list of of mapped libs */
} Link_map;
struct r_debug {
int r_version; /* not used */
struct link_map *r_map; /* list of loaded images */
void (*r_brk)(struct r_debug *, struct link_map *);
/* pointer to break point */
enum {
RT_CONSISTENT, /* things are stable */
RT_ADD, /* adding a shared library */
RT_DELETE /* removing a shared library */
} r_state;
};
struct dl_phdr_info
{
Elf_Addr dlpi_addr; /* module relocation base */
const char *dlpi_name; /* module name */
const Elf_Phdr *dlpi_phdr; /* pointer to module's phdr */
Elf_Half dlpi_phnum; /* number of entries in phdr */
unsigned long long int dlpi_adds; /* total # of loads */
unsigned long long int dlpi_subs; /* total # of unloads */
size_t dlpi_tls_modid;
void *dlpi_tls_data;
};
__BEGIN_DECLS
typedef int (*__dl_iterate_hdr_callback)(struct dl_phdr_info *, size_t,
void *);
extern int dl_iterate_phdr(__dl_iterate_hdr_callback, void *);
__END_DECLS
#endif /* _SYS_LINK_ELF_H_ */

View File

@ -1,627 +0,0 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* 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.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: src/sys/sys/queue.h,v 1.69 2008/05/22 14:40:03 ed Exp $
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
#include <sys/cdefs.h>
/*
* This file defines four types of data structures: singly-linked lists,
* singly-linked tail queues, lists and tail queues.
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A singly-linked tail queue is headed by a pair of pointers, one to the
* head of the list and the other to the tail of the list. The elements are
* singly linked for minimum space and pointer manipulation overhead at the
* expense of O(n) removal for arbitrary elements. New elements can be added
* to the list after an existing element, at the head of the list, or at the
* end of the list. Elements being removed from the head of the tail queue
* should use the explicit macro for this purpose for optimum efficiency.
* A singly-linked tail queue may only be traversed in the forward direction.
* Singly-linked tail queues are ideal for applications with large datasets
* and few or no removals or for implementing a FIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* For details on the use of these macros, see the queue(3) manual page.
*
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
* _NEXT + + + +
* _PREV - - - +
* _LAST - - + +
* _FOREACH + + + +
* _FOREACH_SAFE + + + +
* _FOREACH_REVERSE - - - +
* _FOREACH_REVERSE_SAFE - - - +
* _INSERT_HEAD + + + +
* _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + +
* _INSERT_TAIL - - + +
* _CONCAT - - + +
* _REMOVE_HEAD + - + -
* _REMOVE_NEXT + - + -
* _REMOVE + + + +
*
*/
#ifdef QUEUE_MACRO_DEBUG
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
char * lastfile;
int lastline;
char * prevfile;
int prevline;
};
#define TRACEBUF struct qm_trace trace;
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \
(head)->trace.prevfile = (head)->trace.lastfile; \
(head)->trace.lastline = __LINE__; \
(head)->trace.lastfile = __FILE__; \
} while (0)
#define QMD_TRACE_ELEM(elem) do { \
(elem)->trace.prevline = (elem)->trace.lastline; \
(elem)->trace.prevfile = (elem)->trace.lastfile; \
(elem)->trace.lastline = __LINE__; \
(elem)->trace.lastfile = __FILE__; \
} while (0)
#else
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
#define TRACEBUF
#define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */
/*
* Singly-linked List declarations.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_FOREACH(var, head, field) \
for ((var) = SLIST_FIRST((head)); \
(var); \
(var) = SLIST_NEXT((var), field))
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SLIST_FIRST((head)); \
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
(var) = (tvar))
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &SLIST_FIRST((head)); \
((var) = *(varp)) != NULL; \
(varp) = &SLIST_NEXT((var), field))
#define SLIST_INIT(head) do { \
SLIST_FIRST((head)) = NULL; \
} while (0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
SLIST_NEXT((slistelm), field) = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
SLIST_FIRST((head)) = (elm); \
} while (0)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_REMOVE(head, elm, type, field) do { \
if (SLIST_FIRST((head)) == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = SLIST_FIRST((head)); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_REMOVE_NEXT(head, curelm, field); \
} \
TRASHIT((elm)->field.sle_next); \
} while (0)
#define SLIST_REMOVE_NEXT(head, elm, field) do { \
SLIST_NEXT(elm, field) = \
SLIST_NEXT(SLIST_NEXT(elm, field), field); \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;/* first element */ \
struct type **stqh_last;/* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (0)
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_FOREACH(var, head, field) \
for((var) = STAILQ_FIRST((head)); \
(var); \
(var) = STAILQ_NEXT((var), field))
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = STAILQ_FIRST((head)); \
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_NEXT((tqelm), field) = (elm); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_FIRST((head)) = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? \
NULL : \
((struct type *)(void *) \
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if (STAILQ_FIRST((head)) == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = STAILQ_FIRST((head)); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_NEXT(head, curelm, field); \
} \
TRASHIT((elm)->field.stqe_next); \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if ((STAILQ_FIRST((head)) = \
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_REMOVE_NEXT(head, elm, field) do { \
if ((STAILQ_NEXT(elm, field) = \
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
/*
* List declarations.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
#define QMD_LIST_CHECK_HEAD(head, field) do { \
if (LIST_FIRST((head)) != NULL && \
LIST_FIRST((head))->field.le_prev != \
&LIST_FIRST((head))) \
panic("Bad list head %p first->prev != head", (head)); \
} while (0)
#define QMD_LIST_CHECK_NEXT(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL && \
LIST_NEXT((elm), field)->field.le_prev != \
&((elm)->field.le_next)) \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
#define QMD_LIST_CHECK_PREV(elm, field) do { \
if (*(elm)->field.le_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
#else
#define QMD_LIST_CHECK_HEAD(head, field)
#define QMD_LIST_CHECK_NEXT(elm, field)
#define QMD_LIST_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_FOREACH(var, head, field) \
for ((var) = LIST_FIRST((head)); \
(var); \
(var) = LIST_NEXT((var), field))
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = LIST_FIRST((head)); \
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
(var) = (tvar))
#define LIST_INIT(head) do { \
LIST_FIRST((head)) = NULL; \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
QMD_LIST_CHECK_NEXT(listelm, field); \
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
LIST_NEXT((listelm), field)->field.le_prev = \
&LIST_NEXT((elm), field); \
LIST_NEXT((listelm), field) = (elm); \
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
QMD_LIST_CHECK_PREV(listelm, field); \
(elm)->field.le_prev = (listelm)->field.le_prev; \
LIST_NEXT((elm), field) = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
QMD_LIST_CHECK_HEAD((head), field); \
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
LIST_FIRST((head)) = (elm); \
(elm)->field.le_prev = &LIST_FIRST((head)); \
} while (0)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_REMOVE(elm, field) do { \
QMD_LIST_CHECK_NEXT(elm, field); \
QMD_LIST_CHECK_PREV(elm, field); \
if (LIST_NEXT((elm), field) != NULL) \
LIST_NEXT((elm), field)->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
TRASHIT((elm)->field.le_next); \
TRASHIT((elm)->field.le_prev); \
} while (0)
/*
* Tail queue declarations.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
TRACEBUF \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
TRACEBUF \
}
/*
* Tail queue functions.
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
if (!TAILQ_EMPTY(head) && \
TAILQ_FIRST((head))->field.tqe_prev != \
&TAILQ_FIRST((head))) \
panic("Bad tailq head %p first->prev != head", (head)); \
} while (0)
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
if (*(head)->tqh_last != NULL) \
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
} while (0)
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
if (TAILQ_NEXT((elm), field) != NULL && \
TAILQ_NEXT((elm), field)->field.tqe_prev != \
&((elm)->field.tqe_next)) \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
if (*(elm)->field.tqe_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
#else
#define QMD_TAILQ_CHECK_HEAD(head, field)
#define QMD_TAILQ_CHECK_TAIL(head, headname)
#define QMD_TAILQ_CHECK_NEXT(elm, field)
#define QMD_TAILQ_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
QMD_TRACE_HEAD(head1); \
QMD_TRACE_HEAD(head2); \
} \
} while (0)
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = TAILQ_FIRST((head)); \
(var); \
(var) = TAILQ_NEXT((var), field))
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST((head)); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = TAILQ_LAST((head), headname); \
(var); \
(var) = TAILQ_PREV((var), headname, field))
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
for ((var) = TAILQ_LAST((head), headname); \
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
(var) = (tvar))
#define TAILQ_INIT(head) do { \
TAILQ_FIRST((head)) = NULL; \
(head)->tqh_last = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
QMD_TAILQ_CHECK_NEXT(listelm, field); \
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
TAILQ_NEXT((elm), field)->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else { \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
} \
TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
QMD_TAILQ_CHECK_PREV(listelm, field); \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
TAILQ_NEXT((elm), field) = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
QMD_TAILQ_CHECK_HEAD(head, field); \
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
TAILQ_FIRST((head))->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_FIRST((head)) = (elm); \
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
QMD_TAILQ_CHECK_TAIL(head, field); \
TAILQ_NEXT((elm), field) = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_REMOVE(head, elm, field) do { \
QMD_TAILQ_CHECK_NEXT(elm, field); \
QMD_TAILQ_CHECK_PREV(elm, field); \
if ((TAILQ_NEXT((elm), field)) != NULL) \
TAILQ_NEXT((elm), field)->field.tqe_prev = \
(elm)->field.tqe_prev; \
else { \
(head)->tqh_last = (elm)->field.tqe_prev; \
QMD_TRACE_HEAD(head); \
} \
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
TRASHIT((elm)->field.tqe_next); \
TRASHIT((elm)->field.tqe_prev); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#ifdef _KERNEL
/*
* XXX insque() and remque() are an old way of handling certain queues.
* They bogusly assumes that all queue heads look alike.
*/
struct quehead {
struct quehead *qh_link;
struct quehead *qh_rlink;
};
#ifdef __CC_SUPPORTS___INLINE
static __inline void
insque(void *a, void *b)
{
struct quehead *element = (struct quehead *)a,
*head = (struct quehead *)b;
element->qh_link = head->qh_link;
element->qh_rlink = head;
head->qh_link = element;
element->qh_link->qh_rlink = element;
}
static __inline void
remque(void *a)
{
struct quehead *element = (struct quehead *)a;
element->qh_link->qh_rlink = element->qh_rlink;
element->qh_rlink->qh_link = element->qh_link;
element->qh_rlink = 0;
}
#else /* !__CC_SUPPORTS___INLINE */
void insque(void *a, void *b);
void remque(void *a);
#endif /* __CC_SUPPORTS___INLINE */
#endif /* _KERNEL */
#endif /* !_SYS_QUEUE_H_ */

View File

@ -1,29 +0,0 @@
/*
* \brief err.h prototypes required by ldso
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _ERR_H_
#define _ERR_H_
#ifdef __cplusplus
extern "C" {
#endif
#define err errx
void errx(int eval, const char *fmt, ...) __attribute__((noreturn));
#ifdef __cplusplus
}
#endif
#endif

View File

@ -1,12 +0,0 @@
/*
* \brief Dummy file
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/

View File

@ -1,23 +0,0 @@
/*
* \brief fcntl.h prototypes/definitions required by ldso
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _FCNTL_H_
#define _FCNTL_H_
enum flags {
O_RDONLY = 0x0
};
int open(const char *pathname, int flags);
#endif //_FCNTL_H_

View File

@ -1,63 +0,0 @@
/*
* \brief ldso type definitions
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#ifndef _LDSO_TYPES_H_
#define _LDSO_TYPES_H_
#ifndef __ASSEMBLY__
//from gcc (defines size_t)
#include <stddef.h>
#include <base/fixed_stdint.h>
typedef genode_uint16_t uint16_t;
typedef genode_uint32_t uint32_t;
typedef genode_uint64_t uint64_t;
typedef genode_int32_t int32_t;
typedef genode_int64_t int64_t;
typedef uint32_t u_int32_t;
typedef unsigned long u_long;
typedef char * caddr_t;
typedef uint32_t dev_t;
typedef uint32_t ino_t;
typedef int64_t off_t;
typedef int64_t ssize_t;
typedef int FILE;
typedef unsigned long uintptr_t; //ARM reloc.c, only
extern int *stdout, *stdin, *stderr, errno;
struct stat {
dev_t st_dev;
ino_t st_ino;
};
enum statfs_flags {
MNT_NOEXEC = 0x4
};
struct statfs {
uint32_t f_flags;
char f_mntonname[1];
};
enum {
STDOUT_FILENO,
};
#endif //__ASSEMBLY__
#endif //_LDSO_TYPES_H_

View File

@ -1,14 +0,0 @@
/*
* \brief link.h prototypes/definitions required by ldso
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/
#include <sys/link_elf.h>

View File

@ -1,13 +0,0 @@
/*
* \brief Dummy file
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/

View File

@ -1,12 +0,0 @@
/*
* \brief Dummy file
* \author Sebastian Sumpf
* \date 2009-10-26
*/
/*
* Copyright (C) 2009-2013 Genode Labs GmbH
*
* This file is part of the Genode OS framework, which is distributed
* under the terms of the GNU General Public License version 2.
*/

Some files were not shown because too many files have changed in this diff Show More