1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #define M88 1
24: #include "sysdep.h"
25: #include "bfd.h"
26: #include "libbfd.h"
27: #include "coff/m88k.h"
28: #include "coff/internal.h"
29: #include "libcoff.h"
30:
31: static bfd_boolean m88k_is_local_label_name PARAMS ((bfd *, const char *));
32: static bfd_reloc_status_type m88k_special_reloc
33: PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
34: static void rtype2howto PARAMS ((arelent *, struct internal_reloc *));
35: static void reloc_processing
36: PARAMS ((arelent *, struct internal_reloc *, asymbol **, bfd *, asection *));
37:
38: #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER (3)
39:
40: #define GET_SCNHDR_NRELOC H_GET_32
41: #define GET_SCNHDR_NLNNO H_GET_32
42:
43:
44:
45: #define coff_bfd_is_local_label_name m88k_is_local_label_name
46:
47: static bfd_boolean
48: m88k_is_local_label_name (abfd, name)
49: bfd *abfd ATTRIBUTE_UNUSED;
50: const char *name;
51: {
52: return name[0] == '@';
53: }
54:
55: static bfd_reloc_status_type
56: m88k_special_reloc (abfd, reloc_entry, symbol, data,
57: input_section, output_bfd, error_message)
58: bfd *abfd;
59: arelent *reloc_entry;
60: asymbol *symbol;
61: PTR data;
62: asection *input_section;
63: bfd *output_bfd;
64: char **error_message ATTRIBUTE_UNUSED;
65: {
66: reloc_howto_type *howto = reloc_entry->howto;
67:
68: switch (howto->type)
69: {
70: case R_HVRT16:
71: case R_LVRT16:
72: if (output_bfd != (bfd *) NULL)
73: {
74:
75:
76:
77:
78: reloc_entry->address += input_section->output_offset;
79: }
80: else
81: {
82: bfd_vma output_base = 0;
83: bfd_vma addr = reloc_entry->address;
84: bfd_vma x = bfd_get_16 (abfd, (bfd_byte *) data + addr);
85: asection *reloc_target_output_section;
86: long relocation = 0;
87:
88:
89:
90:
91:
92: if (bfd_is_com_section (symbol->section))
93: relocation = 0;
94: else
95: relocation = symbol->value;
96:
97: reloc_target_output_section = symbol->section->output_section;
98:
99:
100: if (output_bfd)
101: output_base = 0;
102: else
103: output_base = reloc_target_output_section->vma;
104:
105: relocation += output_base + symbol->section->output_offset;
106:
107:
108: relocation += ((reloc_entry->addend << howto->bitsize) + x);
109:
110: reloc_entry->addend = 0;
111:
112: relocation >>= (bfd_vma) howto->rightshift;
113:
114:
115:
116: relocation <<= (bfd_vma) howto->bitpos;
117:
118: if (relocation)
119: bfd_put_16 (abfd, (bfd_vma) relocation,
120: (unsigned char *) data + addr);
121: }
122:
123:
124:
125: if (bfd_is_und_section (symbol->section) && output_bfd == (bfd *) NULL)
126: return bfd_reloc_undefined;
127:
128: return bfd_reloc_ok;
129:
130: default:
131: if (output_bfd != (bfd *) NULL)
132: {
133:
134:
135:
136:
137: reloc_entry->address += input_section->output_offset;
138: return bfd_reloc_ok;
139: }
140: break;
141: }
142:
143: if (output_bfd == (bfd *) NULL)
144: return bfd_reloc_continue;
145:
146: return bfd_reloc_ok;
147: }
148:
149: static reloc_howto_type howto_table[] =
150: {
151: HOWTO (R_PCR16L,
152: 02,
153: 1,
154: 16,
155: TRUE,
156: 0,
157: complain_overflow_signed,
158: m88k_special_reloc,
159: "PCR16L",
160: FALSE,
161: 0x0000ffff,
162: 0x0000ffff,
163: TRUE),
164:
165: HOWTO (R_PCR26L,
166: 02,
167: 2,
168: 26,
169: TRUE,
170: 0,
171: complain_overflow_signed,
172: m88k_special_reloc,
173: "PCR26L",
174: FALSE,
175: 0x03ffffff,
176: 0x03ffffff,
177: TRUE),
178:
179: HOWTO (R_VRT16,
180: 00,
181: 1,
182: 16,
183: FALSE,
184: 0,
185: complain_overflow_bitfield,
186: m88k_special_reloc,
187: "VRT16",
188: FALSE,
189: 0x0000ffff,
190: 0x0000ffff,
191: TRUE),
192:
193: HOWTO (R_HVRT16,
194: 16,
195: 1,
196: 16,
197: FALSE,
198: 0,
199: complain_overflow_dont,
200: m88k_special_reloc,
201: "HVRT16",
202: FALSE,
203: 0x0000ffff,
204: 0x0000ffff,
205: TRUE),
206:
207: HOWTO (R_LVRT16,
208: 00,
209: 1,
210: 16,
211: FALSE,
212: 0,
213: complain_overflow_dont,
214: m88k_special_reloc,
215: "LVRT16",
216: FALSE,
217: 0x0000ffff,
218: 0x0000ffff,
219: TRUE),
220:
221: HOWTO (R_VRT32,
222: 00,
223: 2,
224: 32,
225: FALSE,
226: 0,
227: complain_overflow_bitfield,
228: m88k_special_reloc,
229: "VRT32",
230: FALSE,
231: 0xffffffff,
232: 0xffffffff,
233: TRUE),
234: };
235:
236:
237:
238: static void
239: rtype2howto (cache_ptr, dst)
240: arelent *cache_ptr;
241: struct internal_reloc *dst;
242: {
243: if (dst->r_type >= R_PCR16L && dst->r_type <= R_VRT32)
244: {
245: cache_ptr->howto = howto_table + dst->r_type - R_PCR16L;
246: }
247: else
248: {
249: BFD_ASSERT (0);
250: }
251: }
252:
253: #define RTYPE2HOWTO(cache_ptr, dst) rtype2howto (cache_ptr, dst)
254:
255:
256: #define SWAP_IN_RELOC_OFFSET H_GET_16
257: #define SWAP_OUT_RELOC_OFFSET H_PUT_16
258:
259: #define RELOC_PROCESSING(relent,reloc,symbols,abfd,section) \
260: reloc_processing(relent, reloc, symbols, abfd, section)
261:
262: static void
263: reloc_processing (relent, reloc, symbols, abfd, section)
264: arelent *relent;
265: struct internal_reloc *reloc;
266: asymbol **symbols;
267: bfd *abfd;
268: asection *section;
269: {
270: relent->address = reloc->r_vaddr;
271: rtype2howto (relent, reloc);
272:
273: if (((int) reloc->r_symndx) > 0)
274: {
275: relent->sym_ptr_ptr = symbols + obj_convert (abfd)[reloc->r_symndx];
276: }
277: else
278: {
279: relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
280: }
281:
282: relent->addend = reloc->r_offset;
283: relent->address -= section->vma;
284: }
285:
286: #define BADMAG(x) MC88BADMAG(x)
287: #include "coffcode.h"
288:
289: #undef coff_write_armap
290:
291: CREATE_BIG_COFF_TARGET_VEC (m88kbcs_vec, "coff-m88kbcs", 0, 0, '_', NULL, COFF_SWAP_TABLE)