OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/rtos/ecos-2.0/packages/services/loader/v2_0
    from Rev 27 to Rev 174
    Reverse comparison

Rev 27 → Rev 174

/cdl/loader.cdl
0,0 → 1,245
# ====================================================================
#
# loader.cdl
#
# Dynamic loader configuration data
#
# ====================================================================
#####ECOSGPLCOPYRIGHTBEGIN####
## -------------------------------------------
## This file is part of eCos, the Embedded Configurable Operating System.
## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
##
## eCos is free software; you can redistribute it and/or modify it under
## the terms of the GNU General Public License as published by the Free
## Software Foundation; either version 2 or (at your option) any later version.
##
## eCos is distributed in the hope that it will be useful, but WITHOUT ANY
## WARRANTY; without even the implied warranty of MERCHANTABILITY or
## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
## for more details.
##
## You should have received a copy of the GNU General Public License along
## with eCos; if not, write to the Free Software Foundation, Inc.,
## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
##
## As a special exception, if other files instantiate templates or use macros
## or inline functions from this file, or you compile this file and link it
## with other works to produce a work based on this file, this file does not
## by itself cause the resulting work to be covered by the GNU General Public
## License. However the source code for this file must still be made available
## in accordance with section (3) of the GNU General Public License.
##
## This exception does not invalidate any other reasons why a work based on
## this file might be covered by the GNU General Public License.
##
## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
## at http://sources.redhat.com/ecos/ecos-license/
## -------------------------------------------
#####ECOSGPLCOPYRIGHTEND####
# ====================================================================
######DESCRIPTIONBEGIN####
#
# Author(s): nickg
# Contributors:
# Date: 2000-11-20
#
#####DESCRIPTIONEND####
#
# ====================================================================
 
cdl_package CYGPKG_LOADER {
display "Dynamic loader"
description "
This package provides support for dynamic code loading."
include_dir cyg/loader
compile loader.cxx dload.cxx
 
requires { CYGBLD_ISO_DLFCN_HEADER == "<cyg/loader/dlfcn.h>" }
implements CYGINT_ISO_DLFCN
# ====================================================================
 
cdl_component CYGPKG_LOADER_OPTIONS {
display "Common memory allocator package build options"
flavor none
no_define
description "
Package specific build options including control over
compiler flags used only in building this package,
and details of which tests are built."
 
cdl_option CYGPKG_LOADER_CFLAGS_ADD {
display "Additional compiler flags"
flavor data
no_define
default_value { "" }
description "
This option modifies the set of compiler flags for
building this package. These flags are used in addition
to the set of global flags."
}
 
cdl_option CYGPKG_LOADER_CFLAGS_REMOVE {
display "Suppressed compiler flags"
flavor data
no_define
default_value { "-O2 -fvtable-gc" }
description "
This option modifies the set of compiler flags for
building this package. These flags are removed from
the set of global flags if present."
}
 
cdl_option CYGPKG_LOADER_LDFLAGS_ADD {
display "Additional compiler flags"
flavor data
no_define
# default_value { "-L$(PREFIX)/lib -ldlforce" }
default_value { "" }
description "
This option modifies the set of compiler flags for
building this package. These flags are used in addition
to the set of global flags."
}
 
cdl_option CYGPKG_LOADER_LDFLAGS_REMOVE {
display "Suppressed compiler flags"
flavor data
no_define
default_value { "-Wl,-static -Wl,--gc-sections" }
description "
This option modifies the set of compiler flags for
building this package. These flags are removed from
the set of global flags if present."
}
}
 
# ====================================================================
# Dynamic library build options
 
cdl_option CYGBLD_LOADER_DYNAMIC_LD {
display "Build linker script for dynamic libraries"
flavor bool
default_value 1
description "Build a linker script for creating dynamic libraries"
 
make -priority 50 {
<PREFIX>/lib/dynamic.ld: <PACKAGE>/src/dynamic.ld
$(CC) -E -P -Wp,-MD,dynamic.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $<
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 dynamic.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm dynamic.tmp
 
}
}
 
cdl_option CYGBLD_LOADER_CRTBEGINS {
display "Build special crtbeginS.o for dynamic libraries"
flavor bool
default_value 1
 
make -priority 110 {
<PREFIX>/lib/crtbeginS.o : <PACKAGE>/src/crtbeginS.c
$(CC) -Wp,-MD,crtbeginS.tmp $(INCLUDE_PATH) -g0 -Wall -finhibit-size-directive -fno-inline-functions -fno-exceptions -c -o $@ $<
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 crtbeginS.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm crtbeginS.tmp
}
}
 
cdl_option CYGBLD_LOADER_CRTENDS {
display "Build special crtendS.o for dynamic libraries"
flavor bool
default_value 1
 
make -priority 110 {
<PREFIX>/lib/crtendS.o : <PACKAGE>/src/crtendS.c
$(CC) -Wp,-MD,crtendS.tmp $(INCLUDE_PATH) -g0 -Wall -finhibit-size-directive -fno-inline-functions -fno-exceptions -c -o $@ $<
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 crtendS.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm crtendS.tmp
}
}
cdl_option CYGBLD_LOADER_DLFORCE_LIB {
display "Build dynamic load library"
flavor bool
default_value 1
description "Build a shared library that is to be linked with the executable
to force it to be built in such a way that it is suitable for
having some other shared library load against it. This is the
most portable way of achieving this."
 
make -priority 160 {
<PREFIX>/lib/libdlforce.so : <PACKAGE>/src/dlforce.c
$(CC) $(CFLAGS) -Wp,-MD,dlforce.tmp $(INCLUDE_PATH) -shared -c -o src/dlforce.o $<
$(CC) -g -nostdlib -L$(PREFIX)/lib -shared -Tdynamic.ld -o $@ $(PREFIX)/lib/crtbeginS.o src/dlforce.o $(PREFIX)/lib/crtendS.o
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 dlforce.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm dlforce.tmp
}
}
# ====================================================================
# Tests
 
 
cdl_option CYGBLD_LOADER_TEST_FOO_LIB {
display "Build a dynamic load library"
flavor bool
default_value 1
description "Build a shared library for testing."
 
make {
tests/libfoo.so : <PACKAGE>/tests/foo.c
mkdir -p tests
$(CC) $(CFLAGS) -Wp,-MD,foo.tmp $(INCLUDE_PATH) -shared -c -o tests/foo.o $<
$(CC) $(LDFLAGS) -L$(PREFIX)/lib -shared -Tdynamic.ld -o $@ $(PREFIX)/lib/crtbeginS.o tests/foo.o $(PREFIX)/lib/crtendS.o
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 foo.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm foo.tmp
cc -o entable $(REPOSITORY)/$(PACKAGE)/tests/entable.c
./entable libfoo <tests/libfoo.so >tests/libfoo.so.c
}
}
 
cdl_option CYGBLD_LOADER_TEST_LOADFOO {
display "Build library load test program"
flavor bool
default_value 1
description "Build a test program that will load the test shared library"
 
make {
<PREFIX>/tests/services/loader/current/tests/loadfoo : <PACKAGE>/tests/loadfoo.cxx
mkdir -p $(PREFIX)/tests/services/loader/current/tests
$(CC) $(CFLAGS) -Wp,-MD,loadfoo.tmp $(INCLUDE_PATH) -c -o tests/loadfoo.o $<
# $(CC) $(LDFLAGS) -L$(PREFIX)/lib -Ttarget.ld -ldlforce -o $@ $(PREFIX)/lib/crtbeginS.o tests/loadfoo.o $(PREFIX)/lib/crtendS.o
$(CC) $(LDFLAGS) -Wl,-E -L$(PREFIX)/lib -Ttarget.ld -ldlforce -o $@ tests/loadfoo.o
@echo $@ ": \\" > $(notdir $@).deps
@tail +2 loadfoo.tmp >> $(notdir $@).deps
@echo >> $(notdir $@).deps
@rm loadfoo.tmp
}
}
# cdl_option CYGPKG_LOADER_TESTS {
# display "Tests"
# flavor data
# no_define
# calculated { "tests/loadfoo" }
# description "
# This option specifies the set of tests for this package."
# }
}
 
# ====================================================================
# EOF loader.cdl
/tests/foo.c
0,0 → 1,69
//==========================================================================
//
// foo.c
//
// Test dynamic library
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-25
// Purpose: Test dynamic library
// Description: This file defines a test dynamic library. This contains
// some simple definitions that exercise the dynamic library
// mechanism.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
extern void fee(int);
 
// ------------------------------------------------------------------------
 
int foo_data = 1234;
 
// ------------------------------------------------------------------------
 
void foo(void)
{
fee(foo_data+1);
}
 
//==========================================================================
// End of foo.c
/tests/loadfoo.cxx
0,0 → 1,124
//==========================================================================
//
// loadfoo.cxx
//
// Dynamic library test program
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-20
// Description: Dynamic library test
//
//####DESCRIPTIONEND####
//==========================================================================
 
#include <pkgconf/kernel.h>
#include <pkgconf/hal.h>
 
#include <cyg/infra/testcase.h>
 
//#include <cyg/loader/loader.hxx>
 
#include <dlfcn.h>
 
//==========================================================================
// Include a version of the library ELF file converted to a C table
 
#include "tests/libfoo.so.c"
 
//==========================================================================
 
externC void cyg_dl_force(void);
 
typedef void vfn();
 
int fee_data = 0;
 
//int main( int argc, char **argv )
externC void cyg_start()
{
CYG_TEST_INIT();
 
CYG_TEST_INFO( "LoadFoo: started" );
#if 0
Cyg_LoaderStream_Mem memstream(libfoo, sizeof( libfoo ) );
 
Cyg_LoadObject *obj;
 
// cyg_dl_force();
Cyg_Loader::loader->load( memstream, 0, &obj );
 
vfn *foo = (vfn *)obj->symbol( "foo" );
 
#else
 
void *fooh = dlopenmem( libfoo, sizeof(libfoo), RTLD_NOW );
 
vfn *foo = (vfn *)dlsym( fooh, "foo" );
#endif
 
if( foo )
{
CYG_TEST_INFO( "LoadFoo: foo() call" );
foo();
CYG_TEST_INFO( "LoadFoo: foo() returned" );
}
else
{
CYG_TEST_FAIL_FINISH( "LoadFoo: foo() NULL!!!" );
}
 
CYG_TEST_PASS_FINISH("LoadFoo: OK");
}
 
//==========================================================================
 
externC void fee(int x)
{
CYG_TEST_INFO( "LoadFoo: fee() called" );
fee_data = x;
CYG_TEST_INFO( "LoadFoo: fee() returning" );
}
 
//==========================================================================
// EOF loadfoo.cxx
/tests/entable.c
0,0 → 1,88
//==========================================================================
//
// entable.c
//
// Convert binary file to C table
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-25
// Purpose: Convert binary file to C table
// Description: This is a simple host-side program that converts a binary
// file on it's input to a C format table of unsigned chars
// on its output. The single argument gives the name that the
// table should be given.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <stdio.h>
 
int main( int argc, char **argv )
{
int i;
 
if( argc != 2 )
{
fprintf( stderr, "usage: %s <table name>\n",argv[0]);
exit(1);
}
printf( "unsigned char %s[] = {\n", argv[1]);
 
for(i = 0; ; i++)
{
int c = getchar();
 
if( c == EOF ) break;
 
if( (i % 16) == 0 )
printf("\n\t");
 
printf( "0x%02x, ",c);
}
 
printf("\n};\n");
 
exit(0);
}
 
//==========================================================================
// End of entable.c
/include/mips_elf.h
0,0 → 1,176
#ifndef CYGONCE_LOADER_MIPS_ELF_H
#define CYGONCE_LOADER_MIPS_ELF_H
 
//==========================================================================
//
// mips_elf.h
//
// MIPS specific ELF file format support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-20
// Purpose: Define MIPS ELF support
// Description: This file contains definitions for configuring the dynamic
// loader to deal with the MIPS specific parts of the ELF
// file format.
//
// Usage:
// #include <cyg/loader/mips_elf.h>
// ...
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
 
 
#if defined(CYGPKG_HAL_MIPS)
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#include <cyg/infra/cyg_type.h>
 
//--------------------------------------------------------------------------
// Basic definitions
 
#define CYG_ELF_MACHINE EM_MIPS
 
//--------------------------------------------------------------------------
// Relocation types
// Taken from bfd/include/elf/mips.h - not currently sure which of these
// are actually used in executables.
 
#define R_MIPS_NONE 0
#define R_MIPS_16 1
#define R_MIPS_32 2
#define R_MIPS_REL32 3
#define R_MIPS_26 4
#define R_MIPS_HI16 5
#define R_MIPS_LO16 6
#define R_MIPS_GPREL16 7
#define R_MIPS_LITERAL 8
#define R_MIPS_GOT16 9
#define R_MIPS_PC16 10
#define R_MIPS_CALL16 11
#define R_MIPS_GPREL32 12
/* Irix and MIPS16 relocs currently omitted. */
/* These are GNU extensions to handle embedded-pic. */
#define R_MIPS_PC32 248
#define R_MIPS_PC64 249
#define R_MIPS_GNU_REL16_S2 250
#define R_MIPS_GNU_REL_LO16 251
#define R_MIPS_GNU_REL_HI16 252
/* These are GNU extensions to enable C++ vtable garbage collection. */
#define R_MIPS_GNU_VTINHERIT 253
#define R_MIPS_GNU_VTENTRY 254
 
//--------------------------------------------------------------------------
// Processor specific customization class for Cyg_LoadObject class.
 
#ifdef __cplusplus
 
class Cyg_LoadObject_Proc :
public Cyg_LoadObject_Base
{
public:
 
inline Cyg_LoadObject_Proc()
: Cyg_LoadObject_Base()
{
};
inline Cyg_LoadObject_Proc( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem )
: Cyg_LoadObject_Base( stream, mode, mem )
{
};
 
inline ~Cyg_LoadObject_Proc() {};
 
cyg_code apply_rel( unsigned char type, Elf32_Word sym, Elf32_Addr offset );
 
cyg_code apply_rela( unsigned char type, Elf32_Word sym,
Elf32_Addr offset, Elf32_Sword addend );
};
 
//--------------------------------------------------------------------------
 
inline cyg_code Cyg_LoadObject_Proc::apply_rel( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset )
{
return 0;
}
 
inline cyg_code Cyg_LoadObject_Proc::apply_rela( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset,
Elf32_Sword addend )
{
return 0;
}
 
 
//--------------------------------------------------------------------------
 
#endif // __cplusplus
 
#else // CYG_LOADER_DYNAMIC_LD
 
//--------------------------------------------------------------------------
 
#define CYG_LOADER_DYNAMIC_PREFIX \
OUTPUT_FORMAT("elf32-bigmips", "elf32-bigmips", "elf32-littlemips") \
OUTPUT_ARCH("mips")
 
 
//--------------------------------------------------------------------------
 
#endif // CYG_LOADER_DYNAMIC_LD
 
#endif // defined(CYGPKG_HAL_MIPS)
 
//--------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_MIPS_ELF_H
// End of mips_elf.h
/include/i386_elf.h
0,0 → 1,216
#ifndef CYGONCE_LOADER_I386_ELF_H
#define CYGONCE_LOADER_I386_ELF_H
 
//==========================================================================
//
// i386_elf.h
//
// I386 specific ELF file format support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-20
// Purpose: Define I386 ELF support
// Description: This file contains definitions for configuring the dynamic
// loader to deal with the I386 specific parts of the ELF
// file format.
//
// Usage:
// #include <cyg/loader/i386_elf.h>
// ...
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
 
#if defined(CYGPKG_HAL_I386)
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#include <cyg/infra/cyg_type.h>
 
//--------------------------------------------------------------------------
// Basic definitions
 
#define CYG_ELF_MACHINE EM_386
 
//--------------------------------------------------------------------------
// Relocation types
// Taken from bfd/include/elf/i386.h - not currently sure which of these
// are actually used in executables.
 
#define R_386_NONE 0 /* No reloc */
#define R_386_32 1 /* Direct 32 bit */
#define R_386_PC32 2 /* PC relative 32 bit */
#define R_386_GOT32 3 /* 32 bit GOT entry */
#define R_386_PLT32 4 /* 32 bit PLT address */
#define R_386_COPY 5 /* Copy symbol at runtime */
#define R_386_GLOB_DAT 6 /* Create GOT entry */
#define R_386_JUMP_SLOT 7 /* Create PLT entry */
#define R_386_RELATIVE 8 /* Adjust by program base */
#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
#define R_386_16 20
#define R_386_PC16 21
#define R_386_8 22
#define R_386_PC8 23
#define R_386_max 24
/* These are GNU extensions to enable C++ vtable garbage collection. */
#define R_386_GNU_VTINHERIT 250
#define R_386_GNU_VTENTRY 251
 
//--------------------------------------------------------------------------
// Processor specific customization class for Cyg_LoadObject class.
 
#ifdef __cplusplus
 
class Cyg_LoadObject_Proc :
public Cyg_LoadObject_Base
{
public:
 
inline Cyg_LoadObject_Proc()
: Cyg_LoadObject_Base()
{
};
 
inline Cyg_LoadObject_Proc( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem )
: Cyg_LoadObject_Base( stream, mode, mem )
{
};
 
inline ~Cyg_LoadObject_Proc() {};
 
cyg_code apply_rel( unsigned char type, Elf32_Word sym, Elf32_Addr offset );
 
cyg_code apply_rela( unsigned char type, Elf32_Word sym,
Elf32_Addr offset, Elf32_Sword addend );
};
 
//--------------------------------------------------------------------------
 
inline cyg_code Cyg_LoadObject_Proc::apply_rel( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset )
{
CYG_ADDRESS addr = (CYG_ADDRESS)(offset + base);
CYG_ADDRESS saddr = CYG_LOADER_NULLSYMADDR;
switch( type )
{
 
case R_386_32: /* Direct 32 bit */
saddr = get_sym_addr_from_ix(sym);
if( saddr == CYG_LOADER_NULLSYMADDR )
return CYG_LOADERR_NO_SYMBOL;
*(CYG_WORD32 *)addr += saddr;
break;
case R_386_PC32: /* PC relative 32 bit */
saddr = get_sym_addr_from_ix(sym);
if( saddr == CYG_LOADER_NULLSYMADDR )
return CYG_LOADERR_NO_SYMBOL;
*(CYG_WORD32 *)addr += saddr;
*(CYG_WORD32 *)addr -= (CYG_WORD32)addr;
break;
 
case R_386_GOT32: /* 32 bit GOT entry */
case R_386_PLT32: /* 32 bit PLT address */
case R_386_COPY: /* Copy symbol at runtime */
case R_386_GLOB_DAT: /* Create GOT entry */
case R_386_JUMP_SLOT: /* Create PLT entry */
return CYG_LOADERR_INVALID_RELOC;
case R_386_RELATIVE: /* Adjust by program base */
*(CYG_WORD32 *)addr += base;
break;
 
case R_386_GOTOFF: /* 32 bit offset to GOT */
case R_386_GOTPC: /* 32 bit PC relative offset to GOT */
case R_386_16:
case R_386_PC16:
case R_386_8:
case R_386_PC8:
default:
return CYG_LOADERR_INVALID_RELOC;
}
return 0;
}
 
inline cyg_code Cyg_LoadObject_Proc::apply_rela( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset,
Elf32_Sword addend )
{
// No RELA relocs in i386
return CYG_LOADERR_INVALID_RELOC;
}
 
//--------------------------------------------------------------------------
 
#endif // __cplusplus
 
#else // CYG_LOADER_DYNAMIC_LD
 
//--------------------------------------------------------------------------
 
#define CYG_LOADER_DYNAMIC_PREFIX \
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") \
OUTPUT_ARCH("i386")
 
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
#define CYG_LOADER_DYNAMIC_DATA_ALIGN \
. = ALIGN(0x1000) + (. & (0x1000 - 1));
 
//--------------------------------------------------------------------------
 
#endif // CYG_LOADER_DYNAMIC_LD
 
#endif // defined(CYGPKG_HAL_I386) && __cplusplus
 
//--------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_I386_ELF_H
// End of i386_elf.h
/include/arm_elf.h
0,0 → 1,189
#ifndef CYGONCE_LOADER_ARM_ELF_H
#define CYGONCE_LOADER_ARM_ELF_H
 
//==========================================================================
//
// arm_elf.h
//
// ARM specific ELF file format support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-20
// Purpose: Define ARM ELF support
// Description: This file contains definitions for configuring the dynamic
// loader to deal with the ARM specific parts of the ELF
// file format.
//
// Usage:
// #include <cyg/loader/arm_elf.h>
// ...
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
 
 
#if defined(CYGPKG_HAL_ARM)
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#include <cyg/infra/cyg_type.h>
 
//--------------------------------------------------------------------------
// Basic definitions
 
#define CYG_ELF_MACHINE EM_ARM
 
//--------------------------------------------------------------------------
// Relocation types
// Taken from bfd/include/elf/arm.h - not currently sure which of these
// are actually used in executables.
 
#define R_ARM_NONE 0
#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_COPY 20 /* copy symbol at runtime */
#define R_ARM_GLOB_DAT 21 /* create GOT entry */
#define R_ARM_JUMP_SLOT 22 /* create PLT entry */
#define R_ARM_RELATIVE 23 /* adjust by program base */
#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
#define R_ARM_GOT32 26 /* 32 bit GOT entry */
#define R_ARM_PLT32 27 /* 32 bit PLT address */
#define R_ARM_GNU_VTENTRY 100
#define R_ARM_GNU_VTINHERIT 101
#define R_ARM_THM_PC11 102 /* Cygnus extension to abi: Thumb unconditional branch */
#define R_ARM_THM_PC9 103 /* Cygnus extension to abi: Thumb conditional branch */
#define R_ARM_RXPC25 249
#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
 
 
//--------------------------------------------------------------------------
// Processor specific customization class for Cyg_LoadObject class.
 
#ifdef __cplusplus
 
class Cyg_LoadObject_Proc :
public Cyg_LoadObject_Base
{
public:
 
inline Cyg_LoadObject_Proc()
: Cyg_LoadObject_Base()
{
};
 
inline Cyg_LoadObject_Proc( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem )
: Cyg_LoadObject_Base( stream, mode, mem )
{
};
 
inline ~Cyg_LoadObject_Proc() {};
 
cyg_code apply_rel( unsigned char type, Elf32_Word sym, Elf32_Addr offset );
 
cyg_code apply_rela( unsigned char type, Elf32_Word sym,
Elf32_Addr offset, Elf32_Sword addend );
};
 
//--------------------------------------------------------------------------
 
inline cyg_code Cyg_LoadObject_Proc::apply_rel( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset )
{
return 0;
}
 
inline cyg_code Cyg_LoadObject_Proc::apply_rela( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset,
Elf32_Sword addend )
{
return 0;
}
 
 
//--------------------------------------------------------------------------
 
#endif // __cplusplus
 
#else // CYG_LOADER_DYNAMIC_LD
 
//--------------------------------------------------------------------------
 
#define CYG_LOADER_DYNAMIC_PREFIX \
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") \
OUTPUT_ARCH("arm")
 
//--------------------------------------------------------------------------
 
#endif // CYG_LOADER_DYNAMIC_LD
 
#endif // defined(CYGPKG_HAL_ARM)
 
//--------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_ARM_ELF_H
// End of arm_elf.h
/include/dlfcn.h
0,0 → 1,85
#ifndef CYGONCE_LOADER_DLFCN_H
#define CYGONCE_LOADER_DLFCN_H
 
//==========================================================================
//
// dlfcn.h
//
// ELF dynamic loader API definitions
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-15
// Purpose: Define ELF dynamic loader API
// Description: The functions defined here collectively implement the
// external API of the ELF dynamic loader.
// Usage: #include <cyg/loader/dlfcn.h>
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
 
#include <cyg/infra/cyg_type.h> /* types etc. */
 
// =========================================================================
// Mode values
 
#define RTLD_NOW 0x00 /* Relocate now (default) */
#define RTLD_LAZY 0x01 /* Relocate opportunistically */
#define RTLD_GLOBAL 0x00 /* make symbols available globally (default) */
#define RTLD_LOCAL 0x10 /* keep symbols secret */
 
// =========================================================================
// API calls
 
__externC void *dlopen (const char *file, int mode);
 
__externC void *dlopenmem(const void *addr, size_t size, int mode);
 
__externC int dlclose (void *handle);
 
__externC void *dlsym (void *handle, const char *name);
 
__externC const char *dlerror (void);
 
// -------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_DLFCN_H
// EOF dlfcn.h
/include/elf.h
0,0 → 1,704
#ifndef CYGONCE_LOADER_ELF_H
#define CYGONCE_LOADER_ELF_H
 
//==========================================================================
//
// elf.h
//
// ELF file format definitions
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-15
// Purpose: Define ELF file format
// Description: The types defined here describe the ELF file format.
//
// Usage: #include <cyg/loader/elf.h>
//
//####DESCRIPTIONEND####
//
//==========================================================================
//
// Quite a lot of this file was taken from the BSD exec_elf.h header file.
// Hence we should show you this...
//
/* $OpenBSD: exec_elf.h,v 1.20 1999/09/19 16:16:49 kstailey Exp $ */
/*
* Copyright (c) 1995, 1996 Erik Theisen. 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. 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.
*/
//==========================================================================
 
#include <cyg/infra/cyg_type.h>
 
// -------------------------------------------------------------------------
// Basic types:
 
typedef cyg_uint32 Elf32_Addr;
typedef cyg_uint32 Elf32_Off;
typedef cyg_uint16 Elf32_Half;
typedef cyg_uint32 Elf32_Word;
typedef cyg_int32 Elf32_Sword;
 
typedef cyg_uint64 Elf64_Addr;
typedef cyg_uint64 Elf64_Off;
typedef cyg_uint16 Elf64_Half;
typedef cyg_uint32 Elf64_Word;
typedef cyg_int32 Elf64_Sword;
typedef cyg_uint64 Elf64_Xword;
typedef cyg_int64 Elf64_Sxword;
 
// -------------------------------------------------------------------------
// ELF header
 
#define EI_NIDENT 16
 
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type;
Elf32_Half e_machine;
Elf32_Word e_version;
Elf32_Addr e_entry;
Elf32_Off e_phoff;
Elf32_Off e_shoff;
Elf32_Word e_flags;
Elf32_Half e_ehsize;
Elf32_Half e_phentsize;
Elf32_Half e_phnum;
Elf32_Half e_shentsize;
Elf32_Half e_shnum;
Elf32_Half e_shtrndx;
} Elf32_Ehdr;
 
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shtrndx;
} Elf64_Ehdr;
 
// -------------------------------------------------------------------------
/* e_ident[] identification indexes */
 
#define EI_MAG0 0 /* file ID */
#define EI_MAG1 1 /* file ID */
#define EI_MAG2 2 /* file ID */
#define EI_MAG3 3 /* file ID */
#define EI_CLASS 4 /* file class */
#define EI_DATA 5 /* data encoding */
#define EI_VERSION 6 /* ELF header version */
#define EI_OSABI 7 /* Operating system/ABI identification */
#define EI_ABIVERSION 8 /* ABI version */
#define EI_PAD 9 /* start of pad bytes */
 
// -------------------------------------------------------------------------
/* e_ident[] magic number */
 
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
#define ELFMAG "\177ELF" /* magic */
#define SELFMAG 4 /* size of magic */
 
// -------------------------------------------------------------------------
/* e_ident[] file class */
 
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASS32 1 /* 32-bit objs */
#define ELFCLASS64 2 /* 64-bit objs */
#define ELFCLASSNUM 3 /* number of classes */
 
// -------------------------------------------------------------------------
/* e_ident[] data encoding */
 
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* Little-Endian */
#define ELFDATA2MSB 2 /* Big-Endian */
#define ELFDATANUM 3 /* number of data encode defines */
 
// -------------------------------------------------------------------------
/* 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)
 
// -------------------------------------------------------------------------
/* e_type */
 
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* relocatable file */
#define ET_EXEC 2 /* executable file */
#define ET_DYN 3 /* shared object file */
#define ET_CORE 4 /* core file */
#define ET_NUM 5 /* number of types */
#define ET_LOOS 0xfe00 /* Operating system-specific */
#define ET_HIOS 0xfeff /* Operating system-specific */
#define ET_LOPROC 0xff00 /* reserved range for processor */
#define ET_HIPROC 0xffff /* specific e_type */
 
// -------------------------------------------------------------------------
/* e_machine */
// The following values taken from 22 June 2000 SysV ABI spec, updated with
// extra values from binutils elf/common.h.
 
#define EM_NONE 0 // No machine
#define EM_M32 1 // AT&T WE 32100
#define EM_SPARC 2 // SPARC
#define EM_386 3 // Intel 80386
#define EM_68K 4 // Motorola 68000
#define EM_88K 5 // Motorola 88000
#define EM_860 7 // Intel 80860
#define EM_MIPS 8 // MIPS I Architecture
#define EM_S370 9 // IBM System/370 Processor
#define EM_MIPS_RS3_LE 10 // MIPS RS3000 Little-endian
#define EM_PARISC 15 // Hewlett-Packard PA-RISC
#define EM_VPP500 17 // Fujitsu VPP500
#define EM_SPARC32PLUS 18 // Enhanced instruction set SPARC
#define EM_960 19 // Intel 80960
#define EM_PPC 20 // PowerPC
#define EM_PPC64 21 // 64-bit PowerPC
#define EM_V800 36 // NEC V800
#define EM_FR20 37 // Fujitsu FR20
#define EM_RH32 38 // TRW RH-32
#define EM_RCE 39 // Motorola RCE
#define EM_ARM 40 // Advanced RISC Machines ARM
#define EM_ALPHA 41 // Digital Alpha
#define EM_SH 42 // Hitachi SH
#define EM_SPARCV9 43 // SPARC Version 9
#define EM_TRICORE 44 // Siemens Tricore embedded processor
#define EM_ARC 45 // Argonaut RISC Core, Argonaut Technologies Inc.
#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 architecture
#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 Multimedia Accelerator
#define EM_PCP 55 // Siemens PCP
#define EM_NCPU 56 // Sony nCPU embedded RISC processor
#define EM_NDR1 57 // Denso NDR1 microprocessor
#define EM_STARCORE 58 // Motorola Star*Core processor
#define EM_ME16 59 // Toyota ME16 processor
#define EM_ST100 60 // STMicroelectronics ST100 processor
#define EM_TINYJ 61 // Advanced Logic Corp. TinyJ embedded processor family
#define EM_FX66 66 // Siemens FX66 microcontroller
#define EM_ST9PLUS 67 // STMicroelectronics ST9+ 8/16 bit microcontroller
#define EM_ST7 68 // STMicroelectronics ST7 8-bit microcontroller
#define EM_68HC16 69 // Motorola MC68HC16 Microcontroller
#define EM_68HC11 70 // Motorola MC68HC11 Microcontroller
#define EM_68HC08 71 // Motorola MC68HC08 Microcontroller
#define EM_68HC05 72 // Motorola MC68HC05 Microcontroller
#define EM_SVX 73 // Silicon Graphics SVx
#define EM_ST19 74 // STMicroelectronics ST19 8-bit microcontroller
#define EM_VAX 75 // Digital VAX
#define EM_CRIS 76 // Axis Communications 32-bit embedded processor
#define EM_JAVELIN 77 // Infineon Technologies 32-bit embedded processor
#define EM_FIREPATH 78 // Element 14 64-bit DSP Processor
#define EM_ZSP 79 // LSI Logic 16-bit DSP Processor
#define EM_MMIX 80 // Donald Knuth's educational 64-bit processor
#define EM_HUANY 81 // Harvard University machine-independent object files
#define EM_PRISM 82 // SiTera Prism
 
/* Cygnus PowerPC ELF backend. Written in the absence of an ABI. */
#define EM_CYGNUS_POWERPC 0x9025
 
/* Old version of Sparc v9, from before the ABI; this should be
removed shortly. */
#define EM_OLD_SPARCV9 11
 
/* Old version of PowerPC, this should be removed shortly. */
#define EM_PPC_OLD 17
 
/* Cygnus ARC ELF backend. Written in the absence of an ABI. */
#define EM_CYGNUS_ARC 0x9040
 
/* Cygnus M32R ELF backend. Written in the absence of an ABI. */
#define EM_CYGNUS_M32R 0x9041
 
/* Alpha backend magic number. Written in the absence of an ABI. */
//#define EM_ALPHA 0x9026
 
/* D10V backend magic number. Written in the absence of an ABI. */
#define EM_CYGNUS_D10V 0x7650
 
/* D30V backend magic number. Written in the absence of an ABI. */
#define EM_CYGNUS_D30V 0x7676
 
/* V850 backend magic number. Written in the absense of an ABI. */
#define EM_CYGNUS_V850 0x9080
 
/* mn10200 and mn10300 backend magic numbers.
Written in the absense of an ABI. */
#define EM_CYGNUS_MN10200 0xdead
#define EM_CYGNUS_MN10300 0xbeef
 
/* FR30 magic number - no EABI available. */
#define EM_CYGNUS_FR30 0x3330
 
/* AVR magic number
Written in the absense of an ABI. */
#define EM_AVR 0x1057
 
// -------------------------------------------------------------------------
/* Version */
 
#define EV_NONE 0 /* Invalid */
#define EV_CURRENT 1 /* Current */
#define EV_NUM 2 /* number of versions */
 
// -------------------------------------------------------------------------
/* Section Header */
 
typedef struct {
Elf32_Word sh_name; /* name - index into section header
string table section */
Elf32_Word sh_type; /* type */
Elf32_Word sh_flags; /* flags */
Elf32_Addr sh_addr; /* address */
Elf32_Off sh_offset; /* file offset */
Elf32_Word sh_size; /* section size */
Elf32_Word sh_link; /* section header table index link */
Elf32_Word sh_info; /* extra information */
Elf32_Word sh_addralign; /* address alignment */
Elf32_Word sh_entsize; /* section entry size */
} Elf32_Shdr;
 
typedef struct {
Elf64_Word sh_name; /* section name */
Elf64_Word sh_type; /* section type */
Elf64_Xword sh_flags; /* section flags */
Elf64_Addr sh_addr; /* virtual address */
Elf64_Off sh_offset; /* file offset */
Elf64_Xword sh_size; /* section size */
Elf64_Word sh_link; /* link to another */
Elf64_Word sh_info; /* misc info */
Elf64_Xword sh_addralign; /* memory alignment */
Elf64_Xword sh_entsize; /* table entry size */
} Elf64_Shdr;
 
// -------------------------------------------------------------------------
/* Special Section Indexes */
 
#define SHN_UNDEF 0 /* undefined */
#define SHN_LORESERVE 0xff00 /* lower bounds of reserved indexes */
#define SHN_LOPROC 0xff00 /* reserved range for processor */
#define SHN_HIPROC 0xff1f /* specific section indexes */
#define SHN_LOOS 0xff20 /* reserved range for operating */
#define SHN_HIOS 0xff3f /* system specific section indexes */
#define SHN_ABS 0xfff1 /* absolute value */
#define SHN_COMMON 0xfff2 /* common symbol */
#define SHN_XINDEX 0xffff /* escape value for oversize index */
#define SHN_HIRESERVE 0xffff /* upper bounds of reserved indexes */
 
// -------------------------------------------------------------------------
/* 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 /* relation section without addends */
#define SHT_SHLIB 10 /* reserved - purpose unknown */
#define SHT_DYNSYM 11 /* dynamic symbol table section */
#define SHT_INIT_ARRAY 14 /* init procedure array */
#define SHT_FINI_ARRAY 15 /* fini procedure array */
#define SHT_PREINIT_ARRAY 16 /* preinit procedure array */
#define SHT_GROUP 17 /* section group */
#define SHT_SYMTAB_SHNDX 18 /* oversize index table */
#define SHT_NUM 19 /* number of section types */
#define SHT_LOOS 0x60000000 /* reserved range for O/S */
#define SHT_HIOS 0x6fffffff /* specific section header types */
#define SHT_LOPROC 0x70000000 /* reserved range for processor */
#define SHT_HIPROC 0x7fffffff /* specific section header types */
#define SHT_LOUSER 0x80000000 /* reserved range for application */
#define SHT_HIUSER 0xffffffff /* specific indexes */
 
// -------------------------------------------------------------------------
/* Section names */
 
#define ELF_BSS ".bss" /* uninitialized data */
#define ELF_DATA ".data" /* initialized data */
#define ELF_DEBUG ".debug" /* debug */
#define ELF_DYNAMIC ".dynamic" /* dynamic linking information */
#define ELF_DYNSTR ".dynstr" /* dynamic string table */
#define ELF_DYNSYM ".dynsym" /* dynamic symbol table */
#define ELF_FINI ".fini" /* termination code */
#define ELF_GOT ".got" /* global offset table */
#define ELF_HASH ".hash" /* symbol hash table */
#define ELF_INIT ".init" /* initialization code */
#define ELF_REL_DATA ".rel.data" /* relocation data */
#define ELF_REL_FINI ".rel.fini" /* relocation termination code */
#define ELF_REL_INIT ".rel.init" /* relocation initialization code */
#define ELF_REL_DYN ".rel.dyn" /* relocaltion dynamic link info */
#define ELF_REL_RODATA ".rel.rodata" /* relocation read-only data */
#define ELF_REL_TEXT ".rel.text" /* relocation code */
#define ELF_RODATA ".rodata" /* read-only data */
#define ELF_SHSTRTAB ".shstrtab" /* section header string table */
#define ELF_STRTAB ".strtab" /* string table */
#define ELF_SYMTAB ".symtab" /* symbol table */
#define ELF_TEXT ".text" /* code */
 
// -------------------------------------------------------------------------
/* Section Attribute Flags - sh_flags */
 
#define SHF_WRITE 0x001 /* Writable */
#define SHF_ALLOC 0x002 /* occupies memory */
#define SHF_EXECINSTR 0x004 /* executable */
#define SHF_MERGE 0x010 /* merge data */
#define SHF_STRINGS 0x020 /* contains strings */
#define SHF_INFO_LINK 0x040 /* link in sh_info field */
#define SHF_LINK_ORDER 0x080 /* preserve link order */
#define SHF_OS_NONCONFORMING 0x100 /* special OS-specific */
/* processing needed */
#define SHF_GROUP 0x200 /* member of group */
#define SHF_MASKOS 0x0ff00000 /* reserved bits for OS */
/* specific section attributes */
#define SHF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific section attributes */
 
// -------------------------------------------------------------------------
/* Symbol Table Entry */
 
typedef struct {
Elf32_Word st_name; /* name - index into string table */
Elf32_Addr st_value; /* symbol value */
Elf32_Word st_size; /* symbol size */
unsigned char st_info; /* type and binding */
unsigned char st_other; /* visibility */
Elf32_Half st_shndx; /* section header index */
} Elf32_Sym;
 
typedef struct {
Elf64_Word st_name; /* Symbol name index in str table */
unsigned char st_info; /* type / binding attrs */
unsigned char st_other; /* visibility */
Elf64_Half st_shndx; /* section index of symbol */
Elf64_Addr st_value; /* value of symbol */
Elf64_Xword st_size; /* size of symbol */
} Elf64_Sym;
 
// -------------------------------------------------------------------------
/* Symbol table index */
 
#define STN_UNDEF 0 /* undefined */
 
/* Extract symbol info - st_info */
#define ELF32_ST_BIND(x) ((x) >> 4)
#define ELF32_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF32_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
 
#define ELF64_ST_BIND(x) ((x) >> 4)
#define ELF64_ST_TYPE(x) (((unsigned int) x) & 0xf)
#define ELF64_ST_INFO(b,t) (((b) << 4) + ((t) & 0xf))
 
#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
 
// -------------------------------------------------------------------------
/* Symbol Binding - ELF32_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_NUM 3 /* number of symbol bindings */
#define STB_LOOS 10 /* reserved range for OS */
#define STB_HIOS 12 /* specific symbol bindings */
#define STB_LOPROC 13 /* reserved range for processor */
#define STB_HIPROC 15 /* specific symbol bindings */
 
// -------------------------------------------------------------------------
/* Symbol type - ELF32_ST_TYPE - st_info */
 
#define STT_NOTYPE 0 /* not specified */
#define STT_OBJECT 1 /* data object */
#define STT_FUNC 2 /* function */
#define STT_SECTION 3 /* section */
#define STT_FILE 4 /* file */
#define STT_COMMON 5 /* common block */
#define STT_NUM 6 /* number of symbol types */
#define STT_LOOS 10 /* reserved range for OS */
#define STT_HIOS 12 /* specific symbol types */
#define STT_LOPROC 13 /* reserved range for processor */
#define STT_HIPROC 15 /* specific symbol types */
 
// -------------------------------------------------------------------------
// symbol visibility in st_other
 
#define STV_DEFAULT 0 /* default to binding type */
#define STV_INTERNAL 1 /* processor specific */
#define STV_HIDDEN 2 /* invisible */
#define STV_PROTECTED 3 /* non-premptable */
 
// -------------------------------------------------------------------------
// 32 bit relocation records
 
/* Relocation entry with implicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
} Elf32_Rel;
 
/* Relocation entry with explicit addend */
typedef struct
{
Elf32_Addr r_offset; /* offset of relocation */
Elf32_Word r_info; /* symbol table index and type */
Elf32_Sword r_addend;
} Elf32_Rela;
 
/* Extract relocation info - r_info */
#define ELF32_R_SYM(i) ((i) >> 8)
#define ELF32_R_TYPE(i) ((unsigned char) (i))
#define ELF32_R_INFO(s,t) (((s) << 8) + (unsigned char)(t))
 
// -------------------------------------------------------------------------
// 64 bit equivalents of above structures and macros.
 
typedef struct {
Elf64_Addr r_offset; /* where to do it */
Elf64_Xword r_info; /* index & type of relocation */
} Elf64_Rel;
 
typedef struct {
Elf64_Addr r_offset; /* where to do it */
Elf64_Xword r_info; /* index & type of relocation */
Elf64_Sxword r_addend; /* adjustment value */
} Elf64_RelA;
 
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF)
#define ELF64_R_INFO(s,t) (((s) << 32) + (u_int32_t)(t))
 
// -------------------------------------------------------------------------
/* Program Header */
 
typedef struct {
Elf32_Word p_type; /* segment type */
Elf32_Off p_offset; /* segment offset */
Elf32_Addr p_vaddr; /* virtual address of segment */
Elf32_Addr p_paddr; /* physical address - ignored? */
Elf32_Word p_filesz; /* number of bytes in file for seg. */
Elf32_Word p_memsz; /* number of bytes in mem. for seg. */
Elf32_Word p_flags; /* flags */
Elf32_Word p_align; /* memory alignment */
} Elf32_Phdr;
 
typedef struct {
Elf64_Word p_type; /* entry type */
Elf64_Word p_flags; /* flags */
Elf64_Off p_offset; /* offset */
Elf64_Addr p_vaddr; /* virtual address */
Elf64_Addr p_paddr; /* physical address */
Elf64_Xword p_filesz; /* file size */
Elf64_Xword p_memsz; /* memory size */
Elf64_Xword p_align; /* memory & file alignment */
} Elf64_Phdr;
 
// -------------------------------------------------------------------------
/* Segment types - p_type */
 
#define PT_NULL 0 /* unused */
#define PT_LOAD 1 /* loadable segment */
#define PT_DYNAMIC 2 /* dynamic linking section */
#define PT_INTERP 3 /* the RTLD */
#define PT_NOTE 4 /* auxiliary information */
#define PT_SHLIB 5 /* reserved - purpose undefined */
#define PT_PHDR 6 /* program header */
#define PT_NUM 7 /* Number of segment types */
#define PT_LOOS 0x60000000 /* reserved range for OS */
#define PT_HIOS 0x6fffffff /* specific segment types */
#define PT_LOPROC 0x70000000 /* reserved range for processor */
#define PT_HIPROC 0x7fffffff /* specific segment types */
 
// -------------------------------------------------------------------------
/* Segment flags - p_flags */
 
#define PF_X 0x1 /* Executable */
#define PF_W 0x2 /* Writable */
#define PF_R 0x4 /* Readable */
#define PF_MASKOS 0x0ff00000 /* reserved bits for OS */
/* specific segment flags */
#define PF_MASKPROC 0xf0000000 /* reserved bits for processor */
/* specific segment flags */
 
// -------------------------------------------------------------------------
/* Dynamic structure */
 
typedef struct {
Elf32_Sword d_tag; /* controls meaning of d_val */
union {
Elf32_Word d_val; /* Multiple meanings - see d_tag */
Elf32_Addr d_ptr; /* program virtual address */
} d_un;
} Elf32_Dyn;
 
extern Elf32_Dyn _DYNAMIC[]; /* XXX not 64-bit clean */
 
typedef struct {
Elf64_Sxword d_tag; /* controls meaning of d_val */
union {
Elf64_Xword d_val;
Elf64_Addr d_ptr;
} d_un;
} Elf64_Dyn;
 
// -------------------------------------------------------------------------
/* Dynamic Array Tags - d_tag */
 
#define DT_NULL 0 /* marks end of _DYNAMIC array */
#define DT_NEEDED 1 /* string table offset of needed lib */
#define DT_PLTRELSZ 2 /* size of relocation entries in PLT */
#define DT_PLTGOT 3 /* address PLT/GOT */
#define DT_HASH 4 /* address of symbol hash table */
#define DT_STRTAB 5 /* address of string table */
#define DT_SYMTAB 6 /* address of symbol table */
#define DT_RELA 7 /* address of relocation table */
#define DT_RELASZ 8 /* size of relocation table */
#define DT_RELAENT 9 /* size of relocation entry */
#define DT_STRSZ 10 /* size of string table */
#define DT_SYMENT 11 /* size of symbol table entry */
#define DT_INIT 12 /* address of initialization func. */
#define DT_FINI 13 /* address of termination function */
#define DT_SONAME 14 /* string table offset of shared obj */
#define DT_RPATH 15 /* string table offset of library
search path */
#define DT_SYMBOLIC 16 /* start sym search in shared obj. */
#define DT_REL 17 /* address of rel. tbl. w addends */
#define DT_RELSZ 18 /* size of DT_REL relocation table */
#define DT_RELENT 19 /* size of DT_REL relocation entry */
#define DT_PLTREL 20 /* PLT referenced relocation entry */
#define DT_DEBUG 21 /* bugger */
#define DT_TEXTREL 22 /* Allow rel. mod. to unwritable seg */
#define DT_JMPREL 23 /* add. of PLT's relocation entries */
#define DT_BIND_NOW 24 /* Bind now regardless of env setting */
#define DT_INIT_ARRAY 25 /* init array address */
#define DT_FINI_ARRAY 26 /* fini array address */
#define DT_INIT_ARRAYSZ 27 /* init array size */
#define DT_FINI_ARRAYSZ 28 /* fini array size */
#define DT_RUNPATH 29 /* library search path */
#define DT_FLAGS 30 /* flags */
#define DT_ENCODING 32 /* encoding rules start here */
#define DT_PREINIT_ARRAY 32 /* preinit array address */
#define DT_PREINIT_ARRAYSZ 33 /* preinit array size */
#define DT_NUM 26 /* Number used. */
#define DT_LOOS 0x60000000 /* reserved range for OS */
#define DT_HIOS 0x6fffffff /* specific dynamic array tags */
#define DT_LOPROC 0x70000000 /* reserved range for processor */
#define DT_HIPROC 0x7fffffff /* specific dynamic array tags */
 
// -------------------------------------------------------------------------
// Values for DT_FLAGS entry
 
#define DF_ORIGIN 0x1 /* Uses $ORIGIN substitution string */
#define DF_SYMBOLIC 0x2 /* search for symbols here first */
#define DF_TEXTREL 0x4 /* text may be relocatable */
#define DF_BIND_NOW 0x8 /* bind references now, dammit */
 
// -------------------------------------------------------------------------
/* Note Definitions */
 
typedef struct {
Elf32_Word namesz;
Elf32_Word descsz;
Elf32_Word type;
} Elf32_Note;
 
typedef struct {
Elf64_Word namesz;
Elf64_Word descsz;
Elf64_Word type;
} Elf64_Note;
 
// -------------------------------------------------------------------------
// Hash table structure
// The same structure is used by both 32 and 64 bit formats
 
typedef struct {
Elf32_Word nbucket; /* number of buckets */
Elf32_Word nchain; /* number of chains */
 
/* The buckets follow this structure in memory and the chains
follow those. */
} Elf_Hash;
 
// -------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_ELF_H
// EOF elf.h
/include/loader.hxx
0,0 → 1,487
#ifndef CYGONCE_LOADER_LOADER_HXX
#define CYGONCE_LOADER_LOADER_HXX
 
//==========================================================================
//
// loader.hxx
//
// ELF dynamic loader definitions
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-15
// Purpose: Define ELF dynamic loader
// Description: The classes defined here collectively implement the
// internal API of the ELF dynamic loader.
// Usage: #include <cyg/loader/loader.hxx>
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#include <cyg/loader/elf.h> // ELF data structures
 
#ifdef __cplusplus
 
#include <cyg/kernel/ktypes.h>
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#include <cyg/infra/clist.hxx>
 
// -------------------------------------------------------------------------
// Forward definitions
 
class Cyg_LoaderStream;
class Cyg_LoaderMemBlock;
class Cyg_LoaderMemAlloc;
class Cyg_LoadObject_Base;
class Cyg_LoadObject_Proc;
class Cyg_LoadObject;
class Cyg_Loader;
 
// -------------------------------------------------------------------------
// Error codes
 
#define CYG_LOADERR_NOERROR 0 // No error
#define CYG_LOADERR_NOT_ELF 1 // Not ELF format file
#define CYG_LOADERR_INVALID_CLASS 2 // Not expected file class
#define CYG_LOADERR_INVALID_BYTEORDER 3 // Not expected byte order
#define CYG_LOADERR_INVALID_VERSION 4 // Not expected ELF version
#define CYG_LOADERR_INVALID_MACHINE 5 // Not expected machine type
#define CYG_LOADERR_NO_MEMORY 6 // No memory
#define CYG_LOADERR_EOF 7 // End of input stream
#define CYG_LOADERR_SEEK 8 // Cannot seek to stream position
#define CYG_LOADERR_INVALID_RELOC 9 // Invalid or unexpected relocation
#define CYG_LOADERR_NO_HASHTABLE 10 // No hash table in ELF file
#define CYG_LOADERR_NO_SYMTAB 11 // No symbol table in ELF file
#define CYG_LOADERR_NO_STRTAB 12 // No srting table in ELF file
#define CYG_LOADERR_NO_SYMBOL 13 // Symbol not found
 
// -------------------------------------------------------------------------
// Value for undefined or otherwise invalid symbol addresses.
 
#define CYG_LOADER_NULLSYMADDR 0
 
// -------------------------------------------------------------------------
// Loader Stream base class.
// This defines the interface to data streams that are ELF dynamic executable
// files.
 
class Cyg_LoaderStream
{
public:
 
Cyg_LoaderStream(); // Constructor
 
virtual ~Cyg_LoaderStream(); // Destructor
 
 
// The following functions are virtual and are supplied by a
// derived class to access to data stream.
virtual cyg_code get_byte(CYG_BYTE *val); // Get a byte from the stream
 
virtual cyg_code get_data(CYG_BYTE *addr, CYG_ADDRWORD size);
 
virtual cyg_code seek(CYG_ADDRWORD pos); // seek to given position
 
// The following functions all make use of the virtual functions
// to access the data stream.
cyg_code get_word16(CYG_WORD16 *val); // get a 16 bit value
 
cyg_code get_word32(CYG_WORD32 *val); // get a 32 bit value
 
cyg_code get_word64(CYG_WORD64 *val); // get a 64 bit value
};
 
// -------------------------------------------------------------------------
// Memory allocation object. All memory allocated by the Loader is described
// by one of these.
 
struct Cyg_LoaderMemBlock
: public Cyg_DNode_T<Cyg_LoaderMemBlock>
{
void *address; // data address
cyg_int32 size; // block size
cyg_int32 alignment; // block alignment
Cyg_LoaderMemAlloc *mem; // allocator used
CYG_ADDRESS actual_address; // allocator specific actual address for block
CYG_WORD32 actual_size; // allocator specific actual size for block
 
// Convenience free() function
void free();
};
 
// -------------------------------------------------------------------------
// Memory allocator base class
// This defines the interface to a memory allocator used by the loader.
 
class Cyg_LoaderMemAlloc
{
 
public:
 
Cyg_LoaderMemAlloc();
 
virtual ~Cyg_LoaderMemAlloc();
 
// The following functions are virtual so that alternative memory
// allocators may be implemented. The default behaviour of this
// class is to use malloc/realloc/free to support these functions.
 
// Allocate memory of the supplied size and alignment.
// size - size in bytes
// alignment - alignment expressed as a power of 2
// defaults to 8 byte alignment
virtual Cyg_LoaderMemBlock *alloc( cyg_int32 size,
cyg_int32 alignment = 8);
 
// Reallocate block
// block - block to reallocate
// size - new size in bytes
// alignment - new alignment, -1 if old alignment is to be used.
virtual Cyg_LoaderMemBlock *realloc( Cyg_LoaderMemBlock *block,
cyg_int32 size,
cyg_int32 alignment = -1);
// Free a previously allocated memory segment.
virtual void free( Cyg_LoaderMemBlock *block );
 
};
 
// -------------------------------------------------------------------------
// Cyg_LoaderMemBlock convenience free() function implementation.
 
inline void Cyg_LoaderMemBlock::free() { mem->free(this); };
 
// -------------------------------------------------------------------------
// A loaded object
 
class Cyg_LoadObject_Base
: public Cyg_DNode_T<Cyg_LoadObject>
{
friend class Cyg_Loader;
protected:
// The following fields come from the constructor arguments
 
cyg_uint32 mode; // mode flags
Cyg_LoaderMemAlloc *memalloc; // Memory allocator
 
// The following fields are derived from the ELF header
 
Elf32_Word e_type; // File type
 
Elf32_Addr e_entry; // Executable entry point
 
 
// The following fields are derived from the PT_DYNAMIC segment in
// the program header. These fields are named after the DT_ tags
// that their values are derived from.
Elf32_Word flags; // flags from DT_FLAGS
 
Elf32_Word soname; // name of module, if defined
Elf_Hash *hash; // address of hash table
Elf32_Word *bucket; // derived bucket array address
Elf32_Word *chain; // derived chain array address
// String table
unsigned char *strtab; // address of table
Elf32_Word strsize; // size of table in bytes
 
// Symbol table
Elf32_Sym *symtab; // address of table
Elf32_Word syment; // size of entry
// PTL and GOT
Elf32_Addr pltgot; // address of PLT and/or GOT
 
// PLT relocation entries
Elf32_Addr jmprel; // address of relocation table
Elf32_Word pltrelsz; // size of jmprel table in bytes
Elf32_Word pltrel; // type of table entries: DT_REL
// or DT_RELA
 
// Relocation table with implicit addends
Elf32_Rel *rel; // table address
Elf32_Word relsize; // table size in bytes
Elf32_Word relent; // size of entry
 
// Relocation table with explicit addends
Elf32_Rela *rela; // table address
Elf32_Word relasize; // table size in bytes
Elf32_Word relaent; // size of entry
 
// Init and Fini support
Elf32_Addr init; // address of init function
Elf32_Addr fini; // address of fini function
Elf32_Addr *init_array; // address of init array
Elf32_Word init_array_sz; // size of init array
Elf32_Addr *fini_array; // address of fini array
Elf32_Word fini_array_sz; // size of fini array
Elf32_Addr *pre_init_array; // address of pre_init array
Elf32_Word pre_init_array_sz; // size of pre_init array
 
Elf32_Dyn *dynamic; // address of _DYNAMIC section
CYG_ADDRESS base; // base address used in address and
// relocation calcualtions
Cyg_CList_T<Cyg_LoaderMemBlock> segs; // chain of loaded segments
cyg_code error; // most recent error code
 
 
// private functions
 
void parse_dynamic( Elf32_Dyn *dynamic );
 
// Translate a symbol from its symbol table index into its
// actual address
CYG_ADDRESS get_sym_addr_from_ix( Elf32_Word sym );
 
// Get a symbol from this object's symbol table.
Elf32_Sym *get_sym( Elf32_Word ix );
 
// Get a name from this object's string table.
char *get_name( Elf32_Word offset );
 
// Look up the name in the hash table and return its symbol
// table entry, or NULL if not found.
Elf32_Sym *hash_lookup( const char *name );
 
// Look up the name in the hash table and return its absolute
// address or CYG_LOADER_NULLSYMADDR if it is not found.
CYG_ADDRESS hash_lookup_addr( const char *name );
 
// Standard ELF-defined hash function for symbol table.
static unsigned long elf_hash( const unsigned char *name );
public:
 
// Constructor - reads and allocates the executable.
Cyg_LoadObject_Base();
 
Cyg_LoadObject_Base( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem );
~Cyg_LoadObject_Base(); // Destructor
 
inline cyg_code get_error() { return error; };
// Translate a symbol into its address.
void *symbol( const char *name );
 
// Start this executable running
cyg_code exec(int argc, char **argv, char **envv);
};
 
#endif // __cplusplus
 
#endif // CYG_LOADER_DYNAMIC_LD
 
// -------------------------------------------------------------------------
// All the following files should have suitable ifdefs so that only
// one actually provides content.
 
#include <cyg/loader/mips_elf.h> // MIPS ELF support
#include <cyg/loader/arm_elf.h> // ARM ELF support
#include <cyg/loader/i386_elf.h> // i386 ELF support
#include <cyg/loader/ppc_elf.h> // PowerPC ELF support
//#include <cyg/loader/sparc_elf.h> // Sparc ELF support
//#include <cyg/loader/sh_elf.h> // SH ELF support
 
// -------------------------------------------------------------------------
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#ifdef __cplusplus
 
class Cyg_LoadObject :
public Cyg_LoadObject_Proc
{
Cyg_LoaderMemBlock *block;
public:
 
inline Cyg_LoadObject()
: Cyg_LoadObject_Proc()
{
};
 
inline Cyg_LoadObject( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem,
Cyg_LoaderMemBlock *ablock = NULL)
: Cyg_LoadObject_Proc( stream, mode, mem )
{
block = ablock;
};
inline ~Cyg_LoadObject() {};
 
Cyg_LoaderMemBlock *get_block() { return block; };
// Apply dynamic relocations to the executable
void relocate();
 
// Apply PLT relocations
void relocate_plt();
};
 
// -------------------------------------------------------------------------
// Main loader class
 
class Cyg_Loader
{
// current error code.
cyg_code error;
 
// Default memory allocator.
Cyg_LoaderMemAlloc *mem_default;
 
// Load object for main program
Cyg_LoadObject *main;
 
// List of loaded executables, including the main
// program and all libraries.
Cyg_CList_T<Cyg_LoadObject> loadlist;
 
public:
 
Cyg_Loader( Cyg_LoaderMemAlloc *mem); // Constructor
 
~Cyg_Loader(); // Destructor
 
 
// Load an object and all its dependencies.
cyg_code load( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoadObject **object);
 
// Close an object and remove it from memory
cyg_code close( Cyg_LoadObject *object );
// Translate current error code into a string.
const char *error_string( );
 
// Look up a symbol
Elf32_Sym *hash_lookup( const char *name );
// look up a named symbol in loadlist and return its
// address relocated to its load address.
CYG_ADDRESS hash_lookup_addr( const char *name );
// Static pointer to loader object
static Cyg_Loader *loader;
};
 
//==========================================================================
// Memory based loader stream
 
class Cyg_LoaderStream_Mem
: public Cyg_LoaderStream
{
CYG_ADDRESS base;
CYG_ADDRESS pos;
CYG_ADDRESS end;
public:
Cyg_LoaderStream_Mem( const void *addr, cyg_int32 size );
 
~Cyg_LoaderStream_Mem(); // Destructor
cyg_code get_byte(CYG_BYTE *val); // Get a byte from the stream
 
cyg_code get_data(CYG_BYTE *addr, CYG_ADDRWORD size);
 
cyg_code seek(CYG_ADDRWORD pos); // seek to given position
 
};
 
//==========================================================================
// Fileio based loader stream
 
#ifdef CYGPKG_IO_FILEIO
 
class Cyg_LoaderStream_File
: public Cyg_LoaderStream
{
int fd;
public:
Cyg_LoaderStream_File( int afd );
 
~Cyg_LoaderStream_File(); // Destructor
cyg_code get_byte(CYG_BYTE *val); // Get a byte from the stream
 
cyg_code get_data(CYG_BYTE *addr, CYG_ADDRWORD size);
 
cyg_code seek(CYG_ADDRWORD pos); // seek to given position
 
};
 
#endif
 
// -------------------------------------------------------------------------
 
#endif // __cplusplus
 
#endif // CYG_LOADER_DYNAMIC_LD
 
// -------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_LOADER_HXX
// EOF loader.hxx
/include/ppc_elf.h
0,0 → 1,235
#ifndef CYGONCE_LOADER_PPC_ELF_H
#define CYGONCE_LOADER_PPC_ELF_H
 
//==========================================================================
//
// ppc_elf.h
//
// PowerPC specific ELF file format support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-20
// Purpose: Define PowerPC ELF support
// Description: This file contains definitions for configuring the dynamic
// loader to deal with the PowerPC specific parts of the ELF
// file format.
//
// Usage:
// #include <cyg/loader/ppc_elf.h>
// ...
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
#include <pkgconf/hal.h>
 
#if defined(CYGPKG_HAL_POWERPC)
 
#ifndef CYG_LOADER_DYNAMIC_LD
 
#include <cyg/infra/cyg_type.h>
 
//--------------------------------------------------------------------------
// Basic definitions
 
#define CYG_ELF_MACHINE EM_PPC
 
//--------------------------------------------------------------------------
// Relocation types
// Taken from binutils/include/elf/ppc.h - not currently sure which
// of these are actually used in executables.
 
 
#define R_PPC_NONE 0
#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
 
/* 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
 
/* These are GNU extensions to enable C++ vtable garbage collection. */
#define R_PPC_GNU_VTINHERIT 253
#define R_PPC_GNU_VTENTRY 254
 
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
 
 
//--------------------------------------------------------------------------
// Processor specific customization class for Cyg_LoadObject class.
 
#ifdef __cplusplus
 
class Cyg_LoadObject_Proc :
public Cyg_LoadObject_Base
{
public:
 
inline Cyg_LoadObject_Proc()
: Cyg_LoadObject_Base()
{
};
 
inline Cyg_LoadObject_Proc( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoaderMemAlloc *mem )
: Cyg_LoadObject_Base( stream, mode, mem )
{
};
 
inline ~Cyg_LoadObject_Proc() {};
 
cyg_code apply_rel( unsigned char type, Elf32_Word sym, Elf32_Addr offset );
 
cyg_code apply_rela( unsigned char type, Elf32_Word sym,
Elf32_Addr offset, Elf32_Sword addend );
};
 
//--------------------------------------------------------------------------
 
inline cyg_code Cyg_LoadObject_Proc::apply_rel( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset )
{
return 0;
}
 
inline cyg_code Cyg_LoadObject_Proc::apply_rela( unsigned char type,
Elf32_Word sym,
Elf32_Addr offset,
Elf32_Sword addend )
{
return 0; // CYG_LOADERR_INVALID_RELOC;
}
 
//--------------------------------------------------------------------------
 
externC void abort() CYGBLD_ATTRIB_WEAK;
 
externC void abort() { for(;;); }
 
externC int strcmp(const char *a, const char *b) CYGBLD_ATTRIB_WEAK;
 
externC int strcmp(const char *a, const char *b) { return a==b; }
 
externC unsigned int strlen(const char *a) CYGBLD_ATTRIB_WEAK;
 
externC unsigned int strlen(const char *a) { return 1; }
 
//--------------------------------------------------------------------------
 
#endif // __cplusplus
 
#else // CYG_LOADER_DYNAMIC_LD
 
//--------------------------------------------------------------------------
 
#define CYG_LOADER_DYNAMIC_PREFIX \
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") \
OUTPUT_ARCH("powerpc")
 
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
#define CYG_LOADER_DYNAMIC_DATA_ALIGN \
. = ALIGN(0x1000) + (. & (0x1000 - 1));
 
//--------------------------------------------------------------------------
 
#endif // CYG_LOADER_DYNAMIC_LD
 
#endif // defined(CYGPKG_HAL_POWERPC) && __cplusplus
 
//--------------------------------------------------------------------------
#endif // ifndef CYGONCE_LOADER_PPC_ELF_H
// End of ppc_elf.h
/ChangeLog
0,0 → 1,74
2001-01-05 Nick Garnett <nickg@cygnus.co.uk>
 
* include/ppc_elf.h:
* include/loader.hxx:
Added ppc_elf.h.
 
* include/arm_elf.h: Brought up to date with other files.
 
* docs/notes.txt: Added results of some more investigations.
 
2000-12-15 Nick Garnett <nickg@cygnus.co.uk>
 
* docs/notes.txt:
Notes added to describe what has and has not been done here.
 
* docs/i386.default.ld:
A lightly edited version of the default linker script for Linux
executables. See notes.txt for what this is for.
 
* cdl/loader.cdl:
Added support for dlxxx() API functions.
Various modifications to make rules for various things - these are
only guranteed to work for the linux synthetic target at present.
 
* src/crtbeginS.c:
* src/crtendS.c:
Tidied and made to work (for synthetic target only).
 
* include/loader.hxx:
* src/loader.cxx:
Lots of changes as a result of implementation efforts.
 
* include/i386_elf.h:
Implemented relocations. Added Linker script customizations.
 
* include/elf.h:
Removed buckchain[] array from Elf_Hash structure.
 
* include/dlfcn.h:
Implementation header for the dlxxx() functions.
 
* src/dload.cxx:
Implementation of the dlxxx() functions.
* include/mips_elf.h:
* include/arm_elf.h:
ARM support header added. MIPS support header made compilable.
These are both still incomplete.
 
* src/dynamic.ld: Regenerated by copying and editing Linux script
for shared libraries.
 
* tests/loadfoo.cxx:
Some test infrastructure added and modified to use dlxxx()
functions. Needs more tidying.
 
2000-11-28 Nick Garnett <nickg@cygnus.co.uk>
 
* cdl/loader.cdl:
* include/elf.h:
* include/loader.hxx:
* include/i386_elf.h:
* include/mips_elf.h:
* src/loader.cxx:
* src/crtbeginS.c:
* src/crtendS.c:
* src/dlforce.c:
* src/dynamic.ld:
* tests/foo.c:
* tests/loadfoo.cxx:
* tests/entable.c:
Files created to implement dynamic loader.
This is incomplete - currently checked in for safety.
/src/dlforce.c
0,0 → 1,63
//==========================================================================
//
// dlforce.c
//
// Dummy dynamic library
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-25
// Purpose: Dummy dynamic library
// Description: This file defines a dummy dynamic library. By linking
// this with an executable, we can force the generation of
// the necessary data structures needed to make it possible
// to load further dynamic libraries with it.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
 
void cyg_dl_force(void)
{
return;
}
 
//==========================================================================
// End of dlforce.c
/src/crtbeginS.c
0,0 → 1,127
//==========================================================================
//
// crtbeginS.c
//
// C runtime support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-25
// Purpose: C runtime support
// Description: This file contains code that must appear at the very start of
// a dynamically loaded library. It contains definitions for the
// start of the .init and .fini sections.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
 
#include <cyg/loader/loader.hxx>
 
/*------------------------------------------------------------------------*/
 
#ifndef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP ".section\t.init,\"ax\"\n"
#endif
 
#ifndef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP ".section\t.fini,\"ax\"\n"
#endif
 
#ifndef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP ".text\n"
#endif
 
#ifndef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"aw\"\n"
#endif
 
#ifndef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"aw\"\n"
#endif
 
/*------------------------------------------------------------------------*/
 
typedef void (*pfunc) (void);
 
#if 1
 
asm(CTORS_SECTION_ASM_OP);
static pfunc __CTOR_LIST__[1] __attribute__((unused)) = { (pfunc) -1 };
asm(DTORS_SECTION_ASM_OP);
static pfunc __DTOR_LIST__[1] __attribute__((unused)) = { (pfunc) -1 };
asm(TEXT_SECTION_ASM_OP);
 
#else
 
extern pfunc __CTOR_LIST__[];
extern pfunc __DTOR_LIST__[];
 
#endif
 
/*------------------------------------------------------------------------*/
 
asm (INIT_SECTION_ASM_OP);
 
void __attribute__ ((__unused__))
init_dummy (void)
{
asm( TEXT_SECTION_ASM_OP );
}
 
/*------------------------------------------------------------------------*/
 
asm (FINI_SECTION_ASM_OP);
 
static void __attribute__ ((__unused__))
fini_dummy (void)
{
// __do_global_dtors_aux ();
#ifdef FORCE_FINI_SECTION_ALIGN
FORCE_FINI_SECTION_ALIGN;
#endif
asm (TEXT_SECTION_ASM_OP);
}
 
/*------------------------------------------------------------------------*/
 
//==========================================================================
// End of crtbeginS.c
/src/dynamic.ld
0,0 → 1,216
#define CYG_LOADER_DYNAMIC_LD
 
#include <cyg/loader/loader.hxx>
 
CYG_LOADER_DYNAMIC_PREFIX
 
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0 + SIZEOF_HEADERS;
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.sdata :
{
*(.rel.sdata)
*(.rel.sdata.*)
*(.rel.gnu.linkonce.s*)
}
.rela.sdata :
{
*(.rela.sdata)
*(.rela.sdata.*)
*(.rela.gnu.linkonce.s*)
}
.rel.sbss : { *(.rel.sbss) }
.rela.sbss : { *(.rela.sbss) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init :
{
KEEP (*(.init))
} =0x9090
.plt : { *(.plt) }
.text :
{
*(.text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
} =0x9090
_etext = .;
PROVIDE (etext = .);
.fini :
{
KEEP (*(.fini))
} =0x9090
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
#ifdef CYG_LOADER_DYNAMIC_DATA_ALIGN
CYG_LOADER_DYNAMIC_DATA_ALIGN
#else
. = ALIGN(0x1000);
#endif
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
}
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.sbss :
{
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
_end = .;
PROVIDE (end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}
/src/crtendS.c
0,0 → 1,146
//==========================================================================
//
// crtendS.c
//
// C runtime support
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-25
// Purpose: C runtime support
// Description: This file contains code that must appear at the very end of
// a dynamically loaded library. It contains definitions for the
// end of the .init and .fini sections.
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/system.h>
 
#include <cyg/loader/loader.hxx>
 
/*------------------------------------------------------------------------*/
 
#ifndef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP ".section\t.init,\"ax\"\n"
#endif
 
#ifndef FINI_SECTION_ASM_OP
#define FINI_SECTION_ASM_OP ".section\t.fini,\"ax\"\n"
#endif
 
#ifndef TEXT_SECTION_ASM_OP
#define TEXT_SECTION_ASM_OP ".text\n"
#endif
 
#ifndef CTORS_SECTION_ASM_OP
#define CTORS_SECTION_ASM_OP "\t.section\t.ctors,\"aw\""
#endif
 
#ifndef DTORS_SECTION_ASM_OP
#define DTORS_SECTION_ASM_OP "\t.section\t.dtors,\"aw\""
#endif
 
/*------------------------------------------------------------------------*/
 
typedef void (*pfunc) (void);
 
#if 1
asm(CTORS_SECTION_ASM_OP);
static pfunc __CTOR_END__[1] __attribute__((unused)) = { (pfunc) 0 };
asm(DTORS_SECTION_ASM_OP);
static pfunc __DTOR_END__[] __attribute__((unused)) = { (pfunc) 0 };
asm( TEXT_SECTION_ASM_OP );
 
#else
 
extern pfunc __CTOR_LIST__[];
extern pfunc __CTOR_END__[];
extern pfunc __DTOR_END__[];
 
#endif
 
/*------------------------------------------------------------------------*/
 
static void
cyg_hal_invoke_constructors(void)
{
#if 1
pfunc *p;
 
for (p = &__CTOR_END__[-1]; *p != (pfunc) -1 ; p--)
(*p) ();
#elif 0
pfunc *p;
 
for (p = &__CTOR_LIST__[(int)__CTOR_LIST__[0]]; p != &__CTOR_LIST__[0] ; p--)
(*p) ();
#endif
} // cyg_hal_invoke_constructors()
 
/*------------------------------------------------------------------------*/
 
static void __attribute__ ((__unused__))
init_dummy (void)
{
asm (INIT_SECTION_ASM_OP);
cyg_hal_invoke_constructors();
}
 
asm( TEXT_SECTION_ASM_OP );
 
/*------------------------------------------------------------------------*/
 
static void __attribute__ ((__unused__))
fini_dummy (void)
{
asm (FINI_SECTION_ASM_OP);
// __do_global_dtors_aux ();
#ifdef FORCE_FINI_SECTION_ALIGN
FORCE_FINI_SECTION_ALIGN;
#endif
}
 
asm (TEXT_SECTION_ASM_OP);
 
/*------------------------------------------------------------------------*/
 
//==========================================================================
// End of crtendS.c
/src/dload.cxx
0,0 → 1,199
//==========================================================================
//
// dload.cxx
//
// Dynamic loader API
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-03
// Purpose: Loader class implementation
// Description: This file contains the dynamic ELF loader API.
// This presents the standard dlxxx() calls by invoking
// the loader classes as appropriate.
//
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/hal.h>
#include <pkgconf/kernel.h>
#include <pkgconf/isoinfra.h>
 
#include <cyg/kernel/ktypes.h> // base kernel types
#include <cyg/infra/cyg_trac.h> // tracing macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#include <string.h>
 
#include <cyg/loader/loader.hxx> // Loader header
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dlfcn.h> // API definitions
 
// =========================================================================
// Cyg_LoaderStream_File class
 
// =========================================================================
// API calls
 
cyg_uint32 global_symbol_object;
 
// =========================================================================
// Load and open object
 
__externC void *dlopen (const char *file, int mode)
{
CYG_REPORT_FUNCTION();
 
void *ret = NULL;
 
if( file == NULL )
{
// Special case to allow access to all symbols.
 
ret = (void *)&global_symbol_object;
}
#ifdef CYGPKG_IO_FILEIO
else
{
int fd = open( file, O_RDONLY );
 
if( fd < 0 )
return NULL;
Cyg_LoaderStream_File filestream( fd );
 
Cyg_LoadObject *obj;
 
cyg_code error = Cyg_Loader::loader->load( filestream, mode, &obj );
 
if( error == 0)
{
ret = (void *)obj;
}
 
close( fd );
}
#endif
CYG_REPORT_RETVAL(ret);
return ret;
}
 
// =========================================================================
 
__externC void *dlopenmem(const void *addr, size_t size, int mode)
{
CYG_REPORT_FUNCTION();
 
void *ret = NULL;
 
Cyg_LoaderStream_Mem memstream( addr, size );
 
Cyg_LoadObject *obj;
 
cyg_code error = Cyg_Loader::loader->load( memstream, mode, &obj );
 
if( error == 0)
ret = (void *)obj;
CYG_REPORT_RETVAL(ret);
return ret;
}
 
// =========================================================================
 
__externC int dlclose (void *handle)
{
CYG_REPORT_FUNCTION();
 
int ret = 0;
 
if( handle == (void *)global_symbol_object )
{
// Nothing to do here...
}
else
{
Cyg_LoadObject *obj = (Cyg_LoadObject *)handle;
 
Cyg_Loader::loader->close( obj );
}
CYG_REPORT_RETVAL(ret);
return ret;
}
 
// =========================================================================
 
__externC void *dlsym (void *handle, const char *name)
{
CYG_REPORT_FUNCTION();
 
void *ret = NULL;
 
Cyg_LoadObject *obj = (Cyg_LoadObject *)handle;
 
ret = obj->symbol( name );
CYG_REPORT_RETVAL(ret);
return ret;
}
 
// =========================================================================
 
__externC const char *dlerror (void)
{
CYG_REPORT_FUNCTION();
 
const char *ret = Cyg_Loader::loader->error_string();
 
CYG_REPORT_RETVAL(ret);
return ret;
}
 
 
// =========================================================================
// EOF dload.cxx
/src/loader.cxx
0,0 → 1,1055
//==========================================================================
//
// loader.cxx
//
// Loader class implementation
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): nickg
// Contributors: nickg
// Date: 2000-11-03
// Purpose: Loader class implementation
// Description: This file contains the implementation of the ELF loader
// classes.
//
//
//
//####DESCRIPTIONEND####
//
//==========================================================================
 
#include <pkgconf/hal.h>
#include <pkgconf/kernel.h>
#include <pkgconf/isoinfra.h>
 
#include <cyg/kernel/ktypes.h> // base kernel types
#include <cyg/infra/cyg_trac.h> // tracing macros
#include <cyg/infra/cyg_ass.h> // assertion macros
 
#include <string.h>
 
#include <cyg/loader/loader.hxx> // our header
 
#if CYGINT_ISO_MALLOC
#include <stdlib.h> // for malloc() etc
#endif
 
// ----------------------------------------------------------------------------
 
#ifdef CYGPKG_LIBC_STRING
 
#define streq( a, b ) (strcmp(a,b) == 0)
 
#else
 
static int streq( const char *s1, const char *s2 )
{
while( *s1 == *s2 && *s1 && *s2 ) s1++,s2++;
 
return !(*s2-*s1);
}
 
#endif
 
// ----------------------------------------------------------------------------
// new operator to allow us to invoke constructors on previously allocated
// memory.
 
inline void *operator new(size_t size, void *ptr) { return ptr; };
 
 
// =========================================================================
// Static objects
 
// Default memory allocator
static Cyg_LoaderMemAlloc memalloc;
 
// Loader object
static Cyg_Loader loader(&memalloc);
 
Cyg_Loader *Cyg_Loader::loader = &::loader;
 
 
// =========================================================================
// Main loader class members
 
// -------------------------------------------------------------------------
// Constructor
 
Cyg_Loader::Cyg_Loader( Cyg_LoaderMemAlloc *memalloc )
{
CYG_REPORT_FUNCTION();
 
error = 0;
mem_default = memalloc;
 
// build an object for the main program
Cyg_LoaderMemBlock *obj = mem_default->alloc( sizeof(Cyg_LoadObject));
main = new(obj->address) Cyg_LoadObject( );
 
// Add to load list
loadlist.add_head(main);
error = main->get_error();
 
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Destructor
 
Cyg_Loader::~Cyg_Loader()
{
CYG_REPORT_FUNCTION();
 
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Load an object and all its dependencies.
 
cyg_code Cyg_Loader::load( Cyg_LoaderStream& stream,
cyg_uint32 mode,
Cyg_LoadObject **object)
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG3XV( &stream, mode, object );
 
cyg_code error = 0;
 
Cyg_LoaderMemBlock *obj = mem_default->alloc( sizeof(Cyg_LoadObject));
Cyg_LoadObject *pobj = NULL;
pobj = new(obj->address) Cyg_LoadObject( stream, mode, mem_default, obj );
 
error = pobj->get_error();
 
if( error != 0 )
goto finish;
 
// Add this object to list before we do any relocations to make
// the symbol lookups work.
loadlist.add_tail(pobj);
 
// The object is now loaded. We must now do any relocations.
 
pobj->relocate();
 
error = pobj->get_error();
 
if( error != 0 )
goto finish;
 
// Handle PLT relocations if we are told to do so
 
// We always do this for now..
// if( mode & RTLD_NOW )
pobj->relocate_plt();
 
error = pobj->get_error();
finish:
if( error != 0 )
{
// remove object from list.
loadlist.remove( pobj );
pobj->~Cyg_LoadObject();
mem_default->free( obj );
}
else
{
// return it from this function.
*object = pobj;
}
CYG_REPORT_RETVAL(error);
 
return error;
}
 
// -------------------------------------------------------------------------
// Close object and remove it from memory
 
cyg_code Cyg_Loader::close( Cyg_LoadObject *object )
{
CYG_REPORT_FUNCTION();
 
cyg_code error = 0;
 
Cyg_LoaderMemBlock *block = object->get_block();
object->~Cyg_LoadObject();
 
if( block )
block->free();
CYG_REPORT_RETVAL(error);
 
return error;
}
 
// -------------------------------------------------------------------------
// Translate current error code into a string.
 
const char *Cyg_Loader::error_string( )
{
CYG_REPORT_FUNCTION();
 
char *ret = "";
 
CYG_REPORT_RETVAL(ret);
return ret;
}
 
// -------------------------------------------------------------------------
// Look up a named symbol in loadlist
 
CYG_ADDRESS Cyg_Loader::hash_lookup_addr( const char *name )
{
CYG_ADDRESS addr = 0;
Cyg_LoadObject *object = loadlist.get_head();
do
{
addr = object->hash_lookup_addr( name );
 
if( addr != CYG_LOADER_NULLSYMADDR )
break;
object = object->get_next();
} while( object != loadlist.get_head() );
 
if( addr == CYG_LOADER_NULLSYMADDR )
error = CYG_LOADERR_NO_SYMBOL;
return addr;
}
 
// =========================================================================
// Loader Object class members
 
Cyg_LoadObject_Base::Cyg_LoadObject_Base()
{
e_type = ET_EXEC;
e_entry = 0;
base = 0;
dynamic = _DYNAMIC;
 
parse_dynamic( dynamic );
}
 
// -------------------------------------------------------------------------
// Constructor - reads and allocates the executable.
 
Cyg_LoadObject_Base::Cyg_LoadObject_Base( Cyg_LoaderStream& stream,
cyg_uint32 amode,
Cyg_LoaderMemAlloc *mem )
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG3XV( &stream, mode, mem );
 
Cyg_LoaderMemBlock *phblock = NULL;
Cyg_LoaderMemBlock *block = NULL;
Elf32_Phdr *phdr;
Elf32_Phdr *dynhdr = NULL;
cyg_uint32 memsize = 0;
cyg_uint32 maxalign = 0;
CYG_BYTE *memaddr;
Elf32_Addr vaddr_low = 0x7FFFFFFF;
Elf32_Addr vaddr_hi = 0;
mode = amode;
memalloc = mem;
error = CYG_LOADERR_NOERROR;
// OK, let's start by getting the ELF header...
 
Elf32_Ehdr elf_hdr;
error = stream.get_data( (CYG_BYTE *)&elf_hdr, sizeof( elf_hdr ) );
 
if( error != 0 )
goto finish;
 
// Check that this is a valid ELF file and that the various header
// fields match what we expect for our current architecture and
// platform.
 
if( !IS_ELF( elf_hdr ) )
error = CYG_LOADERR_NOT_ELF;
else if( elf_hdr.e_ident[EI_CLASS] != ELFCLASS32 )
error = CYG_LOADERR_INVALID_CLASS;
#if CYG_BYTEORDER == CYG_LSBFIRST
else if( elf_hdr.e_ident[EI_DATA] != ELFDATA2LSB )
#else
else if( elf_hdr.e_ident[EI_DATA] != ELFDATA2MSB )
#endif
error = CYG_LOADERR_INVALID_BYTEORDER;
else if( elf_hdr.e_ident[EI_VERSION] != EV_CURRENT )
error = CYG_LOADERR_INVALID_VERSION;
else if( elf_hdr.e_machine != CYG_ELF_MACHINE )
error = CYG_LOADERR_INVALID_MACHINE;
else if( elf_hdr.e_version != EV_CURRENT )
error = CYG_LOADERR_INVALID_VERSION;
else if( elf_hdr.e_phentsize != sizeof(Elf32_Phdr) )
error = CYG_LOADERR_INVALID_VERSION;
 
if( error != 0 )
goto finish;
// OK that all seems in order, save some fields away for later.
 
e_type = elf_hdr.e_type;
e_entry = elf_hdr.e_entry;
 
// Now we must read the program header and prepare to read the
// object file into memory.
 
error = stream.seek( elf_hdr.e_phoff );
 
if( error != 0 )
goto finish;
 
 
// Allocate space for the header
phblock = memalloc->alloc( elf_hdr.e_phentsize * elf_hdr.e_phnum );
 
if( phblock == NULL )
{
error = CYG_LOADERR_NO_MEMORY;
goto finish;
}
 
error = stream.get_data( (CYG_BYTE *)phblock->address, sizeof(Elf32_Phdr)*elf_hdr.e_phnum );
 
if( error != 0 )
goto finish;
phdr = (Elf32_Phdr *)phblock->address;
 
// Loop over the program headers, totalling the sizes of the the
// PT_LOAD entries and saving a pointer to the PT_DYNAMIC entry
// when we find it.
// Since the segments must retain the same relationship to
// eachother in memory that their virtual addresses do in the
// headers, we determine the amount of memory needed by finding
// the extent of the virtual addresses covered by the executable.
for( int i = 0; i < elf_hdr.e_phnum; i++,phdr++ )
{
if( phdr->p_type == PT_DYNAMIC )
{
dynhdr = phdr;
continue;
}
if( phdr->p_type != PT_LOAD )
continue;
 
if( phdr->p_vaddr < vaddr_low )
vaddr_low = phdr->p_vaddr;
 
if( (phdr->p_vaddr+phdr->p_memsz) > vaddr_hi )
vaddr_hi = phdr->p_vaddr+phdr->p_memsz;
 
if( phdr->p_align > maxalign )
maxalign = phdr->p_align;
}
 
// Calculate how much memory we need and allocate it
memsize = vaddr_hi - vaddr_low;
block = memalloc->alloc( memsize, maxalign );
 
if( block == NULL )
{
error = CYG_LOADERR_NO_MEMORY;
goto finish;
}
// Attach to segments list
segs.add_tail( block );
// Calculate the base address for this executable. This is the
// difference between the actual address the executable is loaded
// at and its lowest virtual address. This value must be added to
// all addresses derived from the executable to relocate them into
// the real memory space.
 
base = (CYG_ADDRESS)block->address - vaddr_low;
// Loop over the program headers again, this time loading them
// into the memory segment we have allocated and clearing any
// unused areas to zero.
 
phdr = (Elf32_Phdr *)phblock->address;
 
memaddr = (CYG_BYTE *)block->address;
for( int i = 0; i < elf_hdr.e_phnum; i++,phdr++ )
{
if( phdr->p_type != PT_LOAD )
continue;
 
error = stream.seek( phdr->p_offset );
 
if( error != 0 ) break;
 
// Calculate the actual load address for this segment.
CYG_BYTE *loadaddr = (CYG_BYTE *)(phdr->p_vaddr + base);
error = stream.get_data( loadaddr, phdr->p_filesz );
 
if( error != 0 ) break;
 
// If the memory size is more than we got from the file, zero the remainder.
if( phdr->p_filesz < phdr->p_memsz )
memset( loadaddr+phdr->p_filesz,
0,
phdr->p_memsz-phdr->p_filesz );
}
 
 
dynamic = (Elf32_Dyn *)(dynhdr->p_vaddr + base);
 
parse_dynamic( dynamic );
finish:
if( phblock != NULL )
memalloc->free( phblock );
 
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Parse the dynamic segment
 
void Cyg_LoadObject_Base::parse_dynamic( Elf32_Dyn *dynamic )
{
CYG_REPORT_FUNCTION();
 
flags = 0;
for(;; dynamic++)
{
switch( dynamic->d_tag )
{
case DT_NULL: /* marks end of _DYNAMIC array */
return;
case DT_NEEDED: /* string table offset of needed lib */
break; // ignore for now
case DT_PLTRELSZ: /* size of relocation entries in PLT */
pltrelsz = dynamic->d_un.d_val;
break;
case DT_PLTGOT: /* address PLT/GOT */
pltgot = dynamic->d_un.d_ptr + base;
break;
case DT_HASH: /* address of symbol hash table */
hash = (Elf_Hash *)(dynamic->d_un.d_ptr + base);
bucket = (Elf32_Word *)(hash+1);
chain = bucket+hash->nbucket;
break;
case DT_STRTAB: /* address of string table */
strtab = (unsigned char *)(dynamic->d_un.d_ptr + base);
break;
case DT_SYMTAB: /* address of symbol table */
symtab = (Elf32_Sym *)(dynamic->d_un.d_ptr + base);
break;
case DT_RELA: /* address of relocation table */
rela = (Elf32_Rela *)(dynamic->d_un.d_ptr + base);
break;
case DT_RELASZ: /* size of relocation table */
relasize = dynamic->d_un.d_val;
break;
case DT_RELAENT: /* size of relocation entry */
relaent = dynamic->d_un.d_val;
break;
case DT_STRSZ: /* size of string table */
strsize = dynamic->d_un.d_val;
break;
case DT_SYMENT: /* size of symbol table entry */
syment = dynamic->d_un.d_val;
break;
case DT_INIT: /* address of initialization func. */
init = dynamic->d_un.d_ptr + base;
break;
case DT_FINI: /* address of termination function */
fini = dynamic->d_un.d_ptr + base;
break;
case DT_SONAME: /* string table offset of shared obj */
soname = dynamic->d_un.d_val;
break;
case DT_SYMBOLIC: /* start sym search in shared obj. */
flags |= DF_SYMBOLIC;
break;
case DT_REL: /* address of rel. tbl. w addends */
rel = (Elf32_Rel *)(dynamic->d_un.d_ptr + base);
break;
case DT_RELSZ: /* size of DT_REL relocation table */
relsize = dynamic->d_un.d_val;
break;
case DT_RELENT: /* size of DT_REL relocation entry */
relent = dynamic->d_un.d_val;
break;
case DT_PLTREL: /* PLT referenced relocation entry */
pltrel = dynamic->d_un.d_val;
break;
case DT_DEBUG: /* Debug data */
break; /* ignore for now */
case DT_TEXTREL: /* Allow rel. mod. to unwritable seg */
flags |= DF_TEXTREL;
break;
case DT_JMPREL: /* add. of PLT's relocation entries */
jmprel = dynamic->d_un.d_ptr + base;
break;
case DT_BIND_NOW: /* Bind now regardless of env setting */
flags |= DF_BIND_NOW;
break;
case DT_INIT_ARRAY: /* init array address */
init_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);
break;
case DT_FINI_ARRAY: /* fini array address */
fini_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);
break;
case DT_INIT_ARRAYSZ: /* init array size */
init_array_sz = dynamic->d_un.d_val;
break;
case DT_FINI_ARRAYSZ: /* fini array size */
fini_array_sz = dynamic->d_un.d_val;
break;
case DT_FLAGS: /* flags */
flags |= dynamic->d_un.d_val;
break;
case DT_PREINIT_ARRAY: /* preinit array address */
pre_init_array = (Elf32_Addr *)(dynamic->d_un.d_ptr + base);
break;
case DT_PREINIT_ARRAYSZ: /* preinit array size */
pre_init_array_sz = dynamic->d_un.d_val;
break;
default:
// handle format-specific entries
break;
}
}
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Get the symbol name from the current object's symbol table, look it
// up in the hash tables of the loaded objects, and return its address.
 
CYG_ADDRESS Cyg_LoadObject_Base::get_sym_addr_from_ix( Elf32_Word ix )
{
Elf32_Sym *sym = get_sym( ix );
 
if( sym == NULL ) return 0;
 
const char *name = get_name( sym->st_name );
 
// If the symbol has local binding, we must look for
// it in this object only.
if( ELF32_ST_BIND(sym->st_info) == STB_LOCAL )
return hash_lookup_addr( name );
 
// Otherwise search the loaded objects in load order
return Cyg_Loader::loader->hash_lookup_addr( name );
 
}
 
// -------------------------------------------------------------------------
// Lookup the name in our hash table and return the symbol table entry
 
Elf32_Sym *Cyg_LoadObject_Base::hash_lookup( const char *name )
{
Elf32_Sym *ret = NULL;
 
if( hash == NULL )
{
error = CYG_LOADERR_NO_HASHTABLE;
return NULL;
}
 
error = CYG_LOADERR_NO_SYMBOL;
Elf32_Word ix = elf_hash( (const unsigned char *)name );
 
ix %= hash->nbucket;
 
// get head of chain
Elf32_Word iy = bucket[ ix ];
while( iy != STN_UNDEF )
{
Elf32_Sym *sym = get_sym( iy );
const char *sname = get_name( sym->st_name );
 
if( streq( name, sname ) )
{
ret = sym;
error = CYG_LOADERR_NOERROR;
break;
}
 
iy = chain[ iy ];
}
 
return ret;
}
 
// -------------------------------------------------------------------------
// Lookup the given name in our symbol table and return it's value
// relocated to our load address.
 
CYG_ADDRESS Cyg_LoadObject_Base::hash_lookup_addr( const char *name )
{
Elf32_Sym *sym = hash_lookup( name );
 
if( sym == NULL )
return CYG_LOADER_NULLSYMADDR;
 
// Check that this symbol is for a defined object, if its type is
// NOTYPE then it is undefined, here, and we cannot take its address.
// Hopefully it is defined in some other object.
if( ELF32_ST_TYPE(sym->st_info) == STT_NOTYPE )
{
error = CYG_LOADERR_NO_SYMBOL;
return CYG_LOADER_NULLSYMADDR;
}
return sym->st_value + base;
}
 
// -------------------------------------------------------------------------
// ELF hash function
// This is the standard hash function used for indexing the bucket
// array in the hash table.
 
unsigned long Cyg_LoadObject_Base::elf_hash( const unsigned char *name )
{
unsigned long h = 0, g;
 
while( *name )
{
h = ( h << 4 ) + *name++;
if( (g = h & 0xf0000000) != 0 )
h ^= g >> 24;
h &= ~g;
}
return h;
}
 
// -------------------------------------------------------------------------
//
 
Elf32_Sym *Cyg_LoadObject_Base::get_sym( Elf32_Word ix )
{
if( symtab == NULL )
return NULL;
return &symtab[ix];
}
 
char *Cyg_LoadObject_Base::get_name( Elf32_Word offset )
{
if( strtab == NULL || offset > strsize )
return NULL;
return (char *)(&strtab[offset]);
}
 
// -------------------------------------------------------------------------
// Destructor
 
// -------------------------------------------------------------------------
// Cyg_LoadObject_Base destructor
 
Cyg_LoadObject_Base::~Cyg_LoadObject_Base()
{
CYG_REPORT_FUNCTION();
// empty out segments list
while( !segs.empty() )
{
Cyg_LoaderMemBlock *block = segs.rem_head();
 
block->free();
}
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Translate a symbol into its address.
 
void *Cyg_LoadObject_Base::symbol( const char *name )
{
CYG_REPORT_FUNCTION();
 
Elf32_Addr addr = hash_lookup_addr( name );
 
if( addr == CYG_LOADER_NULLSYMADDR )
addr = 0;
CYG_REPORT_RETVAL( addr );
 
return (void *)addr;
}
 
// -------------------------------------------------------------------------
// Start the given executable object running
 
cyg_code Cyg_LoadObject_Base::exec(int argc, char **argv, char **envv)
{
CYG_REPORT_FUNCTION();
CYG_REPORT_FUNCARG3XV( argc, argv, envv );
 
cyg_code error = 0;
CYG_REPORT_RETVAL(error);
 
return error;
}
 
// =========================================================================
// Cyg_LoadObject members
 
// -------------------------------------------------------------------------
// Apply relocations
 
void Cyg_LoadObject::relocate()
{
CYG_REPORT_FUNCTION();
 
if( rel != NULL )
{
Elf32_Rel *r = rel;
for( int i = relsize; i > 0 && error == 0; i -= relent, r++ )
error = apply_rel( ELF32_R_TYPE(r->r_info),
ELF32_R_SYM(r->r_info),
r->r_offset);
}
 
if( error == 0 && rela != NULL )
{
Elf32_Rela *r = rela;
for( int i = relasize; i > 0 && error == 0; i -= relaent, r++ )
error = apply_rela( ELF32_R_TYPE(r->r_info),
ELF32_R_SYM(r->r_info),
r->r_offset,
r->r_addend);
}
CYG_REPORT_RETURN();
}
 
// -------------------------------------------------------------------------
// Apply JMPREL relocations for the PLT
 
void Cyg_LoadObject::relocate_plt()
{
CYG_REPORT_FUNCTION();
 
if( pltrel == DT_REL )
{
Elf32_Rel *r = (Elf32_Rel *)jmprel;
for( int i = pltrelsz; i > 0 && error == 0; i -= sizeof(Elf32_Rel), r++ )
error = apply_rel( ELF32_R_TYPE(r->r_info),
ELF32_R_SYM(r->r_info),
r->r_offset);
}
 
if( error == 0 && pltrel == DT_RELA )
{
Elf32_Rela *r = (Elf32_Rela *)jmprel;
for( int i = pltrelsz; i > 0 && error == 0; i -= sizeof(Elf32_Rela), r++ )
error = apply_rela( ELF32_R_TYPE(r->r_info),
ELF32_R_SYM(r->r_info),
r->r_offset,
r->r_addend);
}
CYG_REPORT_RETURN();
}
 
// =========================================================================
// Loader memory allocator default class methods.
// The default behaviour of this class is to use malloc/realloc/free
// to handle memory.
 
// -------------------------------------------------------------------------
 
Cyg_LoaderMemAlloc::Cyg_LoaderMemAlloc()
{
// no initialization needed
}
 
// -------------------------------------------------------------------------
 
Cyg_LoaderMemAlloc::~Cyg_LoaderMemAlloc()
{
// No destruction needed
}
 
// -------------------------------------------------------------------------
// Allocate memory of the supplied size and alignment.
// size - size in bytes
// alignment - alignment expressed as a power of 2
 
Cyg_LoaderMemBlock *Cyg_LoaderMemAlloc::alloc( cyg_int32 size,
cyg_int32 alignment)
{
#if CYGINT_ISO_MALLOC
Cyg_LoaderMemBlock *block;
cyg_uint8 *mem;
cyg_uint32 acsize = sizeof(Cyg_LoaderMemBlock) + size + alignment;
 
mem = (cyg_uint8 *)::malloc( acsize );
 
if( mem == NULL )
return NULL;
 
block = (Cyg_LoaderMemBlock *)mem;
 
// set up aligned block address
block->address = (void *)((((CYG_ADDRWORD)mem+sizeof(Cyg_LoaderMemBlock))+alignment) & ~(alignment-1));
block->size = size;
block->alignment = alignment;
block->mem = this;
block->actual_address = (CYG_ADDRESS) mem;
block->actual_size = acsize;
 
return block;
 
#else
 
return 0;
 
#endif
}
 
// -------------------------------------------------------------------------
// Reallocate block
 
Cyg_LoaderMemBlock *Cyg_LoaderMemAlloc::realloc( Cyg_LoaderMemBlock *oblock,
cyg_int32 size,
cyg_int32 alignment)
{
#if CYGINT_ISO_MALLOC
Cyg_LoaderMemBlock *block;
cyg_uint8 *mem;
 
if( alignment == -1 )
alignment = oblock->alignment;
cyg_uint32 acsize = sizeof(Cyg_LoaderMemBlock) + size + alignment;
 
mem = (cyg_uint8 *)::realloc( (void *)(oblock->actual_address), acsize );
 
if( mem == NULL )
return NULL;
 
block = (Cyg_LoaderMemBlock *)mem;
 
// set up aligned block address
block->address = (void *)((((CYG_ADDRWORD)mem+sizeof(Cyg_LoaderMemBlock))+alignment) & (alignment-1));
block->size = size;
block->alignment = alignment;
block->mem = this;
block->actual_address = (CYG_ADDRESS) mem;
block->actual_size = acsize;
 
return block;
 
#else
 
return NULL;
 
#endif
}
// -------------------------------------------------------------------------
// Free a previously allocated memory segment.
 
void Cyg_LoaderMemAlloc::free( Cyg_LoaderMemBlock *block )
{
#if CYGINT_ISO_MALLOC
::free( (void *)block->actual_address );
#endif
}
 
// =========================================================================
// Loader stream functions
 
Cyg_LoaderStream::Cyg_LoaderStream()
{
}
 
Cyg_LoaderStream::~Cyg_LoaderStream()
{
}
 
cyg_code Cyg_LoaderStream::get_byte(CYG_BYTE *val)
{
return CYG_LOADERR_EOF;
}
 
cyg_code Cyg_LoaderStream::get_data(CYG_BYTE *addr, CYG_ADDRWORD size)
{
return CYG_LOADERR_EOF;
}
 
cyg_code Cyg_LoaderStream::seek(CYG_ADDRWORD pos)
{
return CYG_LOADERR_SEEK;
}
 
// =========================================================================
// Memory based loader stream
 
Cyg_LoaderStream_Mem::Cyg_LoaderStream_Mem( const void *addr, cyg_int32 size )
{
base = pos = (CYG_ADDRESS)addr;
end = base + size;
}
 
Cyg_LoaderStream_Mem::~Cyg_LoaderStream_Mem()
{
// nothing to do
}
cyg_code Cyg_LoaderStream_Mem::get_byte(CYG_BYTE *val)
{
if( pos == end )
return CYG_LOADERR_EOF;
 
*val = *(CYG_BYTE *)pos;
pos++;
return CYG_LOADERR_NOERROR;
}
 
cyg_code Cyg_LoaderStream_Mem::get_data(CYG_BYTE *addr, CYG_ADDRWORD size)
{
if( pos == end || (pos+size) > end )
return CYG_LOADERR_EOF;
 
memcpy( (void *)addr, (void *)pos, size );
 
pos += size;
return CYG_LOADERR_NOERROR;
}
 
cyg_code Cyg_LoaderStream_Mem::seek(CYG_ADDRWORD apos)
{
CYG_ADDRWORD npos = base+apos;
if( npos > end || npos < base )
return CYG_LOADERR_SEEK;
 
pos = npos;
 
return CYG_LOADERR_NOERROR;
}
 
// =========================================================================
// file based loader stream
 
#ifdef CYGPKG_IO_FILEIO
 
#include <unistd.h>
 
Cyg_LoaderStream_File::Cyg_LoaderStream_File( int afd )
{
fd = afd;
}
 
Cyg_LoaderStream_File::~Cyg_LoaderStream_File()
{
// nothing to do
fd = 0;
}
cyg_code Cyg_LoaderStream_File::get_byte(CYG_BYTE *val)
{
ssize_t got = read( fd, (void *)val, 1 );
if( got == 0 )
return CYG_LOADERR_EOF;
 
return CYG_LOADERR_NOERROR;
}
 
cyg_code Cyg_LoaderStream_File::get_data(CYG_BYTE *addr, CYG_ADDRWORD size)
{
ssize_t got = read( fd, (void *)addr, size );
if( got != (ssize_t)size )
return CYG_LOADERR_EOF;
 
return CYG_LOADERR_NOERROR;
}
 
cyg_code Cyg_LoaderStream_File::seek(CYG_ADDRWORD apos)
{
off_t npos = lseek( fd, apos, SEEK_SET );
if( npos != apos )
return CYG_LOADERR_SEEK;
 
return CYG_LOADERR_NOERROR;
}
 
#endif
 
// =========================================================================
// EOF loader.cxx
/docs/notes.txt
0,0 → 1,107
 
These notes were written to record the current state of this code.
Much of it was written during the investigation work.
 
At present this stuff is only partially functional. Do not assume
anything works. In particular things like constructor/destructors and
init/fini sections have not been fully implemented.
 
 
Initial Investigations
======================
 
Attempts to build a simple shared library using the existing
tools. Command line is something like:
 
xxx-gcc -shared -o libfoo.so foo.so
 
 
arm-elf no - includes crt0 which fails to find main() etc.
thumb-elf no - includes crt0 which fails to find main() etc.
i686-pc-linux-gnu yes
i386-elf no - tries to build program
mn10300 no - tries to build program
powerpc-eabi no - implicit ref to libc.so
sh-elf no - tries to build program
sparclite no - fails to find crtn.o
mips-tx39-elf yes - but seriously mangles PHDR DYNAMIC section
mips66vr4300-elf yes - but seriously mangles PHDR DYNAMIC section
 
 
Building new Toolchains
=======================
 
Given the poor results from our standard toolchains, it was decided to
try and use Linux-targeted toolchains, which are guranteed to have the
necessary support.
 
These builds all use bindutils-2.1.1, gcc-2.95.2 and gdb-5.0.
 
arm-unknown-linux-gnu build of libgcc fails looking for asm/unistd.h
 
All MIPS Linux toolchains use collect2 constructors, so no priorities.
MIPS support also requires PIC code support, which needs HAL
changes. In this case it is fairly easy since the assembler does a lot
of the conversion for us but there are still some things that need
fixing.
 
MIPS BSD toolchains fail building libgcc, but adding files from
openbsd sources allows these to build. However, these then fail to
build proper PIC code and omit some features.
 
PowerPC toolchains need to use the full ABI, not the ebedded one, with
TOCs and all the trimmings. This requires major changes to the
HAL. Or maybe not - not too sure about this one.
 
Since we are having so much difficulty getting any of these to work,
try to get it running on the i686-pc-linux-gnu synthetic target, since
we know that works.
 
 
Synthetic Target
================
 
To enable a progam to be capable of loading a shared library it must
include a DYNAMIC section. This includes the symbol, string and hash
tables needed to satisfy any references from the loaded library back
to the executable. The only way I have so far worked out to make this
happen is to link the executable against a dynamic library. This needs
the -Wl,-static flag to be removed.
 
A simple library, libdlforce.so has been created to make this
happen. It is not even necessary for the progam to call into the
library, just having it on the command line is enough.
 
 
Generation of usable libraries and executables is very sensitive to
the exact form of the linker scripts used.
 
src/dynamic.ld has been replaced by a very lightly edited copy of
i686-pc-linux-gnu/H-i686-pc-linux-gnu/i686-pc-linux-gnu/lib/ldscripts/elf_i386.xs
 
To make the main executable work correctly the i386.dynamic.ld script
in this directory must be copied over target.ld before building any
programs. I have not yet worked out what the problems are, but the
original target.ld causes programs built for dynamic loading to
SIGSEGV in ld.so.
 
If we try to use the POSIX package, we get spurious calls to
pthread_mutex_unlock() from somewhere in the Linux runtime. This may
be a result of using a different linker script, however.
 
 
Retesting toolchains
====================
 
Having got the synthetic target sort-of working, now go back and see
what happens when configuring each of our standard toolchains for the
loader.
 
arm-elf - build of shared library with external references
result in "undefined reference to `fee'".
 
mips-tx39-elf - mangles DYNAMIC section as before.
 
powerpc-eabi - Compiler selects a libgcc.a that contains references
to "abort" and "strcmp". With these defined we get
sensible looking libraries.
/docs/i386.default.ld
0,0 → 1,224
OUTPUT_FORMAT("elf32-i386", "elf32-i386",
"elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
STARTUP(vectors.o)
ENTRY(_start)
INPUT(extras.o)
GROUP(libtarget.a libgcc.a)
SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/local/tools/i686-pc-linux-gnu/H-i686-pc-linux-gnu/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/local/tools/i686-pc-linux-gnu/H-i686-pc-linux-gnu/i686-pc-linux-gnu/lib);
/* Do we need any of these for elf?
__DYNAMIC = 0; */
SECTIONS
{
/* Read-only sections, merged into text segment: */
. = 0 + SIZEOF_HEADERS;
.hash : { *(.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rel.init : { *(.rel.init) }
.rela.init : { *(.rela.init) }
.rel.text :
{
*(.rel.text)
*(.rel.text.*)
*(.rel.gnu.linkonce.t*)
}
.rela.text :
{
*(.rela.text)
*(.rela.text.*)
*(.rela.gnu.linkonce.t*)
}
.rel.fini : { *(.rel.fini) }
.rela.fini : { *(.rela.fini) }
.rel.rodata :
{
*(.rel.rodata)
*(.rel.rodata.*)
*(.rel.gnu.linkonce.r*)
}
.rela.rodata :
{
*(.rela.rodata)
*(.rela.rodata.*)
*(.rela.gnu.linkonce.r*)
}
.rel.data :
{
*(.rel.data)
*(.rel.data.*)
*(.rel.gnu.linkonce.d*)
}
.rela.data :
{
*(.rela.data)
*(.rela.data.*)
*(.rela.gnu.linkonce.d*)
}
.rel.ctors : { *(.rel.ctors) }
.rela.ctors : { *(.rela.ctors) }
.rel.dtors : { *(.rel.dtors) }
.rela.dtors : { *(.rela.dtors) }
.rel.got : { *(.rel.got) }
.rela.got : { *(.rela.got) }
.rel.sdata :
{
*(.rel.sdata)
*(.rel.sdata.*)
*(.rel.gnu.linkonce.s*)
}
.rela.sdata :
{
*(.rela.sdata)
*(.rela.sdata.*)
*(.rela.gnu.linkonce.s*)
}
.rel.sbss : { *(.rel.sbss) }
.rela.sbss : { *(.rela.sbss) }
.rel.bss : { *(.rel.bss) }
.rela.bss : { *(.rela.bss) }
.rel.plt : { *(.rel.plt) }
.rela.plt : { *(.rela.plt) }
.init :
{
KEEP (*(.init))
} =0x9090
.plt : { *(.plt) }
.text :
{
_stext = .;
*(.text)
*(.text.*)
*(.stub)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
} =0x9090
_etext = .;
PROVIDE (etext = .);
.fini :
{
KEEP (*(.fini))
} =0x9090
.rodata : { *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) }
.rodata1 : { *(.rodata1) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = ALIGN(0x1000) + (. & (0x1000 - 1));
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.eh_frame : { KEEP (*(.eh_frame)) }
.gcc_except_table : { *(.gcc_except_table) }
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
__CTOR_LIST__ = ABSOLUTE(.);
KEEP (*crtbegin.o(.ctors))
/* We don't want to include the .ctor section from
from the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = ABSOLUTE(.);
}
.dtors :
{
__DTOR_LIST__ = ABSOLUTE(.);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = ABSOLUTE(.);
}
.got : { *(.got.plt) *(.got) }
.dynamic : { *(.dynamic) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
}
_edata = .;
PROVIDE (edata = .);
__bss_start = .;
.sbss :
{
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections. */
. = ALIGN(32 / 8);
}
. = ALIGN(32 / 8);
__bss_end = .;
_end = .;
__heap1 = ALIGN (0x10);
PROVIDE (end = .);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.