]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/loader/v2_0/include/i386_elf.h
Initial revision
[karo-tx-redboot.git] / packages / services / loader / v2_0 / include / i386_elf.h
1 #ifndef CYGONCE_LOADER_I386_ELF_H
2 #define CYGONCE_LOADER_I386_ELF_H
3
4 //==========================================================================
5 //
6 //      i386_elf.h
7 //
8 //      I386 specific ELF file format support
9 //
10 //==========================================================================
11 //####ECOSGPLCOPYRIGHTBEGIN####
12 // -------------------------------------------
13 // This file is part of eCos, the Embedded Configurable Operating System.
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 //
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
19 //
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 // for more details.
24 //
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 //
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
35 //
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
38 //
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
45 //
46 // Author(s):    nickg
47 // Contributors: nickg
48 // Date:         2000-11-20
49 // Purpose:      Define I386 ELF support
50 // Description:  This file contains definitions for configuring the dynamic
51 //               loader to deal with the I386 specific parts of the ELF
52 //               file format.
53 //              
54 // Usage:
55 //              #include <cyg/loader/i386_elf.h>
56 //              ...
57 //              
58 //
59 //####DESCRIPTIONEND####
60 //
61 //==========================================================================
62
63 #include <pkgconf/system.h>
64 #include <pkgconf/hal.h>
65
66 #if defined(CYGPKG_HAL_I386)
67
68 #ifndef CYG_LOADER_DYNAMIC_LD
69
70 #include <cyg/infra/cyg_type.h>
71
72 //--------------------------------------------------------------------------
73 // Basic definitions
74
75 #define CYG_ELF_MACHINE     EM_386
76
77 //--------------------------------------------------------------------------
78 // Relocation types
79 // Taken from bfd/include/elf/i386.h - not currently sure which of these
80 // are actually used in executables.
81
82 #define R_386_NONE              0       /* No reloc */
83 #define R_386_32                1       /* Direct 32 bit  */
84 #define R_386_PC32              2       /* PC relative 32 bit */
85 #define R_386_GOT32             3       /* 32 bit GOT entry */
86 #define R_386_PLT32             4       /* 32 bit PLT address */
87 #define R_386_COPY              5       /* Copy symbol at runtime */
88 #define R_386_GLOB_DAT          6       /* Create GOT entry */
89 #define R_386_JUMP_SLOT         7       /* Create PLT entry */
90 #define R_386_RELATIVE          8       /* Adjust by program base */
91 #define R_386_GOTOFF            9       /* 32 bit offset to GOT */
92 #define R_386_GOTPC             10      /* 32 bit PC relative offset to GOT */
93 #define R_386_16                20
94 #define R_386_PC16              21
95 #define R_386_8                 22
96 #define R_386_PC8               23
97 #define R_386_max               24
98      /* These are GNU extensions to enable C++ vtable garbage collection.  */
99 #define R_386_GNU_VTINHERIT     250
100 #define R_386_GNU_VTENTRY       251
101
102 //--------------------------------------------------------------------------
103 // Processor specific customization class for Cyg_LoadObject class.
104
105 #ifdef __cplusplus
106
107 class Cyg_LoadObject_Proc :
108       public Cyg_LoadObject_Base
109 {
110  public:
111
112     inline Cyg_LoadObject_Proc()
113         : Cyg_LoadObject_Base()
114         {
115         };
116
117     inline Cyg_LoadObject_Proc( Cyg_LoaderStream& stream,
118                     cyg_uint32 mode,
119                     Cyg_LoaderMemAlloc *mem )
120         : Cyg_LoadObject_Base( stream, mode, mem )
121         {
122         };
123
124     inline ~Cyg_LoadObject_Proc() {};
125
126     cyg_code apply_rel( unsigned char type, Elf32_Word sym, Elf32_Addr offset );
127
128     cyg_code apply_rela( unsigned char type, Elf32_Word sym,
129                          Elf32_Addr offset, Elf32_Sword addend );
130 };
131
132 //--------------------------------------------------------------------------
133
134 inline cyg_code Cyg_LoadObject_Proc::apply_rel( unsigned char type,
135                                                 Elf32_Word sym,
136                                                 Elf32_Addr offset )
137 {
138     CYG_ADDRESS addr = (CYG_ADDRESS)(offset + base);
139     CYG_ADDRESS saddr = CYG_LOADER_NULLSYMADDR;
140     
141     switch( type )
142     {
143
144     case R_386_32:                          /* Direct 32 bit  */
145         saddr = get_sym_addr_from_ix(sym);
146         if( saddr == CYG_LOADER_NULLSYMADDR )
147             return CYG_LOADERR_NO_SYMBOL;
148         *(CYG_WORD32 *)addr += saddr;
149         break;
150         
151     case R_386_PC32:                        /* PC relative 32 bit */
152         saddr = get_sym_addr_from_ix(sym);
153         if( saddr == CYG_LOADER_NULLSYMADDR )
154             return CYG_LOADERR_NO_SYMBOL;
155         *(CYG_WORD32 *)addr += saddr;
156         *(CYG_WORD32 *)addr -= (CYG_WORD32)addr;
157         break;
158
159     case R_386_GOT32:                       /* 32 bit GOT entry */
160     case R_386_PLT32:                       /* 32 bit PLT address */
161     case R_386_COPY:                        /* Copy symbol at runtime */
162     case R_386_GLOB_DAT:                    /* Create GOT entry */
163     case R_386_JUMP_SLOT:                   /* Create PLT entry */
164         return CYG_LOADERR_INVALID_RELOC;
165         
166     case R_386_RELATIVE:                    /* Adjust by program base */
167         *(CYG_WORD32 *)addr += base;
168         break;
169
170     case R_386_GOTOFF:                      /* 32 bit offset to GOT */
171     case R_386_GOTPC:                       /* 32 bit PC relative offset to GOT */
172     case R_386_16:
173     case R_386_PC16:
174     case R_386_8:
175     case R_386_PC8:
176     default:
177         return CYG_LOADERR_INVALID_RELOC;
178     }
179     return 0;
180 }
181
182 inline cyg_code Cyg_LoadObject_Proc::apply_rela( unsigned char type,
183                                                  Elf32_Word sym,
184                                                  Elf32_Addr offset,
185                                                  Elf32_Sword addend )
186 {
187     // No RELA relocs in i386
188     return CYG_LOADERR_INVALID_RELOC;
189 }
190
191 //--------------------------------------------------------------------------
192
193 #endif // __cplusplus
194
195 #else // CYG_LOADER_DYNAMIC_LD
196
197 //--------------------------------------------------------------------------
198
199 #define CYG_LOADER_DYNAMIC_PREFIX                                               \
200         OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")     \
201         OUTPUT_ARCH("i386")
202
203 /* Adjust the address for the data segment.  We want to adjust up to
204    the same address within the page on the next page up.  */
205 #define CYG_LOADER_DYNAMIC_DATA_ALIGN                   \
206         . = ALIGN(0x1000) + (. & (0x1000 - 1));
207
208 //--------------------------------------------------------------------------
209
210 #endif // CYG_LOADER_DYNAMIC_LD
211
212 #endif // defined(CYGPKG_HAL_I386) && __cplusplus
213
214 //--------------------------------------------------------------------------
215 #endif // ifndef CYGONCE_LOADER_I386_ELF_H
216 // End of i386_elf.h