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
- from Rev 27 to Rev 174
- ↔ Reverse comparison
Rev 27 → Rev 174
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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. |
|
/v2_0/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 |
/v2_0/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 |
/v2_0/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 . */ |
} |
/v2_0/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 |
/v2_0/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 |
/v2_0/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 |
/v2_0/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. |
/v2_0/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 . */ |
} |