1 /****************************************************************************
2 *
3 *                            Open Watcom Project
4 *
5 *    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6 *
7 *  ========================================================================
8 *
9 *    This file contains Original Code and/or Modifications of Original
10 *    Code as defined in and that are subject to the Sybase Open Watcom
11 *    Public License version 1.0 (the 'License'). You may not use this file
12 *    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13 *    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14 *    provided with the Original Code and Modifications, and is also
15 *    available at www.sybase.com/developer/opensource.
16 *
17 *    The Original Code and all software distributed under the License are
18 *    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19 *    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20 *    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22 *    NON-INFRINGEMENT. Please see the License for the specific language
23 *    governing rights and limitations under the License.
24 *
25 *  ========================================================================
26 *
27 * Description:  fixup related variables and routines
28 *
29 ****************************************************************************/
30 
31 #ifndef FIXUP_H
32 #define FIXUP_H
33 
34 /* RELOFF8 - RELOFF32 must be consecutive */
35 
36 enum fixup_types {
37         FIX_VOID = 0,       /*  0, fixup is to be ignored */
38         FIX_RELOFF8,        /*  1, 1 byte */
39         FIX_RELOFF16,       /*  2, 2 byte */
40         FIX_RELOFF32,       /*  3, 4 byte */
41         FIX_OFF8,           /*  4, 1 byte, OMF, BIN + GNU-ELF only */
42         FIX_OFF16,          /*  5, 2 byte */
43         FIX_OFF32,          /*  6, 4 byte */
44 #if AMD64_SUPPORT
45         FIX_OFF64,          /*  7, 8 byte, COFF64, ELF64 + BIN only */
46 #endif
47         FIX_SEG = 8,        /*  8, 2 byte */
48         FIX_PTR16,          /*  9, 4 byte, OMF+BIN-MZ only */
49         FIX_PTR32,          /* 10, 6 byte, OMF+BIN-MZ only */
50         FIX_HIBYTE,         /* 11, 1 byte, OMF+BIN-MZ only */
51         FIX_OFF32_IMGREL,   /* 12, 4 byte, COFF+ELF only */
52         FIX_OFF32_SECREL,   /* 13, 4 byte, COFF+ELF only */
53         FIX_LAST
54 };
55 
56 /*  OMF: nothing (7, 12, 13 can't happen)
57  * COFF: set bit 1, 4, 9, 10, 11
58  *  ELF: set bit 8, 9, 10, 11
59  */
60 #if BIN_SUPPORT
61 #define BIN_DISALLOWED 0x0000
62 #endif
63 #define OMF_DISALLOWED 0x0000
64 #if COFF_SUPPORT
65 /* exclude RELOFF8, OFF8, PTR16, PTR32, HIBYTE */
66 #define COFF32_DISALLOWED 0x0E12
67 /* exclude RELOFF8, OFF8, PTR16, PTR32, HIBYTE */
68 #define COFF64_DISALLOWED 0x0E12
69 #endif
70 #if ELF_SUPPORT
71 /* exclude SEG, PTR16, PTR32, HIBYTE */
72 #define ELF32_DISALLOWED  0x0F00
73 /* exclude SEG, PTR16, PTR32, HIBYTE */
74 #define ELF64_DISALLOWED  0x0F00
75 #endif
76 
77 /* fixups are also used for backpatching of forward references in pass one.
78  * the instructions which depend on the distance are CALL, JMP, PUSH <imm>.
79  * OPTJ_EXPLICIT: JMP SHORT <label> or Jcc SHORT <label>, size cannot change
80  * OPTJ_EXTEND:   Jcc <label> for cpu < 80386, size may change (2 -> 5/7 or 8/10)
81  * OPTJ_JXX:      Jcc <label> for cpu >= 80386, size may change (2 -> 5 )
82  * OPTJ_CALL:     call <label>, may become push cs, call NEAR or call FAR
83  * OPTJ_PUSH:     push <label>, assumed byte, may become variable or label.
84  */
85 
86 enum fixup_options {
87         OPTJ_NONE,      /* normal jump */
88         OPTJ_EXPLICIT,
89         OPTJ_EXTEND,
90         OPTJ_JXX,
91         OPTJ_CALL,
92         OPTJ_PUSH      /* PUSH */
93 };
94 
95 struct fixup {
96     struct fixup         *nextbp;       /* PASS 1: linked list backpatch */
97     struct fixup         *nextrlc;      /* PASS >1: linked list relocs */
98 #ifdef TRMEM
99     uint_16              marker;
100 #endif
101     uint_32              offset;        /* symbol's offset */
102     uint_32              locofs;        /* location of fixup */
103     enum fixup_types     type;
104     enum fixup_options   option;
105     union {
106         uint_16 flags;
107         struct {
108 #if AMD64_SUPPORT
109             /* the IP relative addressing needs to know where the instruction ends.
110              * the result <end of instruction> - <fixup location> is stored here.
111              */
112             uint_8        addbytes;
113 #endif
114             unsigned char loader_resolved:1;        /* operator LROFFSET */
115             unsigned char orgoccured:1;             /* v2.04 ORG occured behind this fix */
116 #if FASTMEM==0
117             unsigned char count:2;                  /* v2.14 ref count */
118 #endif
119         };
120     };
121     union {
122         struct {
123             int_8           frame_type;     /* frame specifier (SEG=0,GRP=1,,...) */
124             uint_16         frame_datum;    /* additional data, usually index */
125         };
126         struct asym         *segment_var;   /* symbol's segment if assembly time var */
127     };
128     struct dsym             *def_seg;       /* segment the fixup is in - pass 1 only */
129     struct asym             *sym;
130 };
131 
132 extern struct fixup  *CreateFixup( struct asym *sym, enum fixup_types fixup_type, enum fixup_options fixup_option );
133 extern void          SetFixupFrame( const struct asym *sym, char );
134 extern void          FreeFixup( struct fixup * );
135 extern void          store_fixup( struct fixup *, struct dsym *, int_32 * );
136 
137 extern ret_code      BackPatch( struct asym *sym );
138 
139 #endif
140