gas/
[deliverable/binutils-gdb.git] / gas / config / obj-evax.c
1 /* obj-evax.c - EVAX (openVMS/Alpha) object file format.
2 Copyright 1996, 1997, 2005, 2007, 2008, 2009, 2010, 2011, 2012
3 Free Software Foundation, Inc.
4 Contributed by Klaus Kämpf (kkaempf@progis.de) of
5 proGIS Software, Aachen, Germany.
6 Extensively enhanced by Douglas Rupp of AdaCore.
7
8 This file is part of GAS, the GNU Assembler
9
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3, or (at your option)
13 any later version.
14
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to
22 the Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
24
25 #define OBJ_HEADER "obj-evax.h"
26
27 #include "as.h"
28 #include "bfd.h"
29 #include "vms.h"
30 #include "subsegs.h"
31 #include "struc-symbol.h"
32 #include "safe-ctype.h"
33
34 static void s_evax_weak (int);
35 static unsigned int crc32 (unsigned char *, int);
36 static char *encode_32 (unsigned int);
37 static char *encode_16 (unsigned int);
38 static int decode_16 (const char *);
39
40 const pseudo_typeS obj_pseudo_table[] =
41 {
42 { "weak", s_evax_weak, 0},
43 {0, 0, 0},
44 }; /* obj_pseudo_table */
45
46 void obj_read_begin_hook () {}
47
48 /* Handle the weak specific pseudo-op. */
49
50 static void
51 s_evax_weak (int ignore ATTRIBUTE_UNUSED)
52 {
53 char *name;
54 int c;
55 symbolS *symbolP;
56 char *stop = NULL;
57 char stopc;
58
59 if (flag_mri)
60 stop = mri_comment_field (&stopc);
61
62 do
63 {
64 name = input_line_pointer;
65 c = get_symbol_end ();
66 symbolP = symbol_find_or_make (name);
67 *input_line_pointer = c;
68 SKIP_WHITESPACE ();
69 S_SET_WEAK (symbolP);
70 if (c == ',')
71 {
72 input_line_pointer++;
73 SKIP_WHITESPACE ();
74 if (*input_line_pointer == '\n')
75 c = '\n';
76 }
77 }
78 while (c == ',');
79
80 if (flag_mri)
81 mri_comment_end (stop, stopc);
82
83 demand_empty_rest_of_line ();
84 }
85
86 void
87 evax_symbol_new_hook (symbolS *sym)
88 {
89 struct evax_private_udata_struct *udata;
90
91 udata = (struct evax_private_udata_struct *)
92 xmalloc (sizeof (struct evax_private_udata_struct));
93
94 udata->bsym = symbol_get_bfdsym (sym);
95 udata->enbsym = NULL;
96 udata->origname = xstrdup (S_GET_NAME (sym));
97 udata->lkindex = 0;
98 symbol_get_bfdsym(sym)->udata.p = (PTR) udata;
99 }
100
101 void
102 evax_frob_symbol (symbolS *sym, int *punt)
103 {
104 const char *symname = S_GET_NAME (sym);
105 int symlen = strlen (symname);
106 asymbol *symbol = symbol_get_bfdsym (sym);
107
108 if (symlen > 4
109 && strcmp (symname + symlen - 4, "..en") == 0
110 && S_GET_SEGMENT (sym) == undefined_section)
111 {
112 symbol_clear_used_in_reloc (sym);
113 *punt = 1;
114 }
115
116 else if ((symbol->flags & BSF_GLOBAL) && (symbol->flags & BSF_FUNCTION))
117 {
118 struct evax_private_udata_struct *udata
119 = (struct evax_private_udata_struct *)symbol->udata.p;
120
121 /* Fix up equates of function definitions. */
122 while (udata->enbsym == NULL)
123 {
124 /* ??? Equates have been resolved at this point so their
125 expression is O_constant; but they previously were
126 O_symbol and we hope the equated symbol is still there. */
127 sym = symbol_get_value_expression (sym)->X_add_symbol;
128 if (sym == NULL)
129 {
130 as_bad (_("no entry symbol for global function '%s'"), symname);
131 return;
132 }
133 symbol = symbol_get_bfdsym (sym);
134 udata->enbsym
135 = ((struct evax_private_udata_struct *)symbol->udata.p)->enbsym;
136 }
137 }
138 }
139
140 void
141 evax_frob_file_before_adjust (void)
142 {
143 struct alpha_linkage_fixups *l;
144 segT current_section = now_seg;
145 int current_subsec = now_subseg;
146 segment_info_type *seginfo;
147 int linkage_index = 1;
148
149 subseg_set (alpha_link_section, 0);
150 seginfo = seg_info (alpha_link_section);
151
152 /* Handle .linkage fixups. */
153 for (l = alpha_linkage_fixup_root; l != NULL; l = l->next)
154 {
155 if (S_GET_SEGMENT (l->fixp->fx_addsy) == alpha_link_section)
156 {
157 /* The symbol is defined in the file. The linkage entry decays to
158 two relocs. */
159 symbolS *entry_sym;
160 fixS *fixpentry, *fixppdesc, *fixtail;
161
162 fixtail = seginfo->fix_tail;
163
164 /* Replace the linkage with the local symbols */
165 entry_sym = symbol_find
166 (((struct evax_private_udata_struct *)symbol_get_bfdsym (l->fixp->fx_addsy)->udata.p)->enbsym->name);
167 if (!entry_sym)
168 abort ();
169 fixpentry = fix_new (l->fixp->fx_frag, l->fixp->fx_where, 8,
170 entry_sym, l->fixp->fx_offset, 0,
171 BFD_RELOC_64);
172 fixppdesc = fix_new (l->fixp->fx_frag, l->fixp->fx_where + 8, 8,
173 l->fixp->fx_addsy, l->fixp->fx_offset, 0,
174 BFD_RELOC_64);
175 l->fixp->fx_size = 0;
176 l->fixp->fx_done = 1;
177
178 /* If not already at the tail, splice the new fixups into
179 the chain right after the one we are nulling out */
180 if (fixtail != l->fixp)
181 {
182 fixppdesc->fx_next = l->fixp->fx_next;
183 l->fixp->fx_next = fixpentry;
184 fixtail->fx_next = 0;
185 seginfo->fix_tail = fixtail;
186 }
187 }
188 else
189 {
190 /* Assign a linkage index. */
191 ((struct evax_private_udata_struct *)
192 symbol_get_bfdsym (l->label)->udata.p)->lkindex = linkage_index;
193
194 l->fixp->fx_addnumber = linkage_index;
195
196 linkage_index += 2;
197 }
198 }
199
200 subseg_set (current_section, current_subsec);
201 }
202
203 void
204 evax_frob_file_before_fix (void)
205 {
206 /* Now that the fixups are done earlier, we need to transfer the values
207 into the BFD symbols before calling fix_segment (ideally should not
208 be done also later). */
209 if (symbol_rootP)
210 {
211 symbolS *symp;
212
213 /* Set the value into the BFD symbol. Up til now the value
214 has only been kept in the gas symbolS struct. */
215 for (symp = symbol_rootP; symp; symp = symbol_next (symp))
216 symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
217 }
218 }
219
220 /* The length is computed from the maximum allowable length of 64 less the
221 4 character ..xx extension that must be preserved (removed before
222 krunching and appended back on afterwards). The $<nnn>.. prefix is
223 also removed and prepened back on, but doesn't enter into the length
224 computation because symbols with that prefix are always resolved
225 by the assembler and will never appear in the symbol table. At least
226 I hope that's true, TBD. */
227 #define MAX_LABEL_LENGTH 60
228
229 static char *shorten_identifier (char *);
230 static int is_truncated_identifier (char *);
231
232 char *
233 evax_shorten_name (char *id)
234 {
235 int prefix_dotdot = 0;
236 char prefix [64];
237 int len = strlen (id);
238 int suffix_dotdot = len;
239 char suffix [64];
240 char *base_id;
241
242 /* This test may be too conservative. */
243 if (len <= MAX_LABEL_LENGTH)
244 return id;
245
246 suffix [0] = 0;
247 prefix [0] = 0;
248
249 /* Check for ..xx suffix and save it. */
250 if (strncmp (&id[len-4], "..", 2) == 0)
251 {
252 suffix_dotdot = len - 4;
253 strncpy (suffix, &id[len-4], 4);
254 suffix [4] = 0;
255 }
256
257 /* Check for $<nnn>.. prefix and save it. */
258 if ((id[0] == '$') && ISDIGIT (id[1]))
259 {
260 int i;
261
262 for (i=2; i < len; i++)
263 {
264 if (!ISDIGIT (id[i]))
265 {
266 if (id[i] == '.' && id [i+1] == '.')
267 {
268 prefix_dotdot = i+2;
269 strncpy (prefix, id, prefix_dotdot);
270 prefix [prefix_dotdot] = 0;
271 }
272 break;
273 }
274 }
275 }
276
277 /* We only need worry about krunching the base symbol. */
278 base_id = xmalloc (suffix_dotdot - prefix_dotdot + 1);
279 strncpy (base_id, &id[prefix_dotdot], suffix_dotdot - prefix_dotdot);
280 base_id [suffix_dotdot - prefix_dotdot] = 0;
281
282 if (strlen (base_id) > MAX_LABEL_LENGTH)
283 {
284 char new_id [4096];
285 char *return_id;
286
287 strcpy (new_id, base_id);
288
289 /* Shorten it. */
290 strcpy (new_id, shorten_identifier (new_id));
291
292 /* Prepend back the prefix if there was one. */
293 if (prefix_dotdot)
294 {
295 memmove (&new_id [prefix_dotdot], new_id, strlen (new_id) + 1);
296 strncpy (new_id, prefix, prefix_dotdot);
297 }
298
299 /* Append back the suffix if there was one. */
300 if (strlen (suffix))
301 strcat (new_id, suffix);
302
303 /* Save it on the heap and return. */
304 return_id = xmalloc (strlen (new_id) + 1);
305 strcpy (return_id, new_id);
306
307 return return_id;
308 }
309 else
310 return id;
311 }
312
313 /* The code below implements a mechanism for truncating long
314 identifiers to an arbitrary length (set by MAX_LABEL_LENGTH).
315
316 It attempts to make each truncated identifier unique by replacing
317 part of the identifier with an encoded 32-bit CRC and an associated
318 checksum (the checksum is used as a way to determine that the name
319 was truncated).
320
321 Note that both a portion of the start and of the end of the
322 identifier may be kept. The macro ID_SUFFIX_LENGTH will return the
323 number of characters in the suffix of the identifier that should be
324 kept.
325
326 The portion of the identifier that is going to be removed is
327 checksummed. The checksum is then encoded as a 5-character string,
328 the characters of which are then summed. This sum is then encoded
329 as a 3-character string. Finally, the original length of the
330 identifier is encoded as a 3-character string.
331
332 These three strings are then concatenated together (along with an _h
333 which further designates that the name was truncated):
334
335 "original_identifier"_haaaaabbbccc
336
337 aaaaa = 32-bit CRC
338 bbb = length of original identifier
339 ccc = sum of 32-bit CRC characters
340
341 The resulting identifier will be MAX_LABEL_LENGTH characters long.
342
343 */
344
345
346 /* Table used to convert an integer into a string. */
347
348 static const char codings[] = {
349 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
350 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
351 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
352 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
353 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_'};
354
355 /* The number of codings in the above table. */
356 static const int number_of_codings = sizeof (codings) / sizeof (char);
357
358 /* Table used by decode_16 () to convert an encoded string back into
359 an integer. */
360 static char decodings[256];
361
362 /* Table used by the crc32 function to calcuate the checksum. */
363 static unsigned int crc32_table[256] = {0, 0};
364
365 /* Given a string in BUF, calculate a 32-bit CRC for it.
366
367 This is used as a reasonably unique hash for the given string. */
368
369 static unsigned int
370 crc32 (unsigned char *buf, int len)
371 {
372 unsigned int crc = 0xffffffff;
373
374 if (! crc32_table[1])
375 {
376 /* Initialize the CRC table and the decoding table. */
377 int i, j;
378 unsigned int c;
379
380 for (i = 0; i < 256; i++)
381 {
382 for (c = i << 24, j = 8; j > 0; --j)
383 c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
384 crc32_table[i] = c;
385 decodings[i] = 0;
386 }
387 for (i = 0; i < number_of_codings; i++)
388 decodings[codings[i] & 255] = i;
389 }
390
391 while (len--)
392 {
393 crc = (crc << 8) ^ crc32_table[(crc >> 24) ^ *buf];
394 buf++;
395 }
396 return crc;
397 }
398
399 /* Encode the lower 32 bits of VALUE as a 5-character string. */
400
401 static char *
402 encode_32 (unsigned int value)
403 {
404 static char res[6];
405 int x;
406
407 res[5] = 0;
408 for(x = 0; x < 5; x++)
409 {
410 res[x] = codings[value % number_of_codings];
411 value = value / number_of_codings;
412 }
413 return res;
414 }
415
416 /* Encode the lower 16 bits of VALUE as a 3-character string. */
417
418 static char *
419 encode_16 (unsigned int value)
420 {
421 static char res[4];
422 int x;
423
424 res[3] = 0;
425 for(x = 0; x < 3; x++)
426 {
427 res[x] = codings[value % number_of_codings];
428 value = value / number_of_codings;
429 }
430 return res;
431 }
432
433 /* Convert the encoded string obtained from encode_16 () back into a
434 16-bit integer. */
435
436 static int
437 decode_16 (const char *string)
438 {
439 return decodings[(int) string[2]] * number_of_codings * number_of_codings
440 + decodings[(int) string[1]] * number_of_codings
441 + decodings[(int) string[0]];
442 }
443
444 /* ID_SUFFIX_LENGTH is used to determine how many characters in the
445 suffix of the identifier are to be preserved, if any. */
446
447 #ifndef ID_SUFFIX_LENGTH
448 #define ID_SUFFIX_LENGTH(ID) (0)
449 #endif
450
451 /* Return a reasonably-unique version of NAME that is less than or
452 equal to MAX_LABEL_LENGTH characters long. The string returned from
453 this function may be a copy of NAME; the function will never
454 actually modify the contents of NAME. */
455
456 static char newname[MAX_LABEL_LENGTH + 1];
457
458 static char *
459 shorten_identifier (char *name)
460 {
461 int crc, len, sum, x, final_len;
462 char *crc_chars;
463 int suffix_length = ID_SUFFIX_LENGTH (name);
464
465 if ((len = strlen (name)) <= MAX_LABEL_LENGTH)
466 return name;
467
468 final_len = MAX_LABEL_LENGTH - 2 - 5 - 3 - 3 - suffix_length;
469 crc = crc32 ((unsigned char *)name + final_len,
470 len - final_len - suffix_length);
471 crc_chars = encode_32 (crc);
472 sum = 0;
473 for (x = 0; x < 5; x++)
474 sum += crc_chars [x];
475 strncpy (newname, name, final_len);
476 newname [MAX_LABEL_LENGTH] = 0;
477 /* Now append the suffix of the original identifier, if any. */
478 if (suffix_length)
479 strncpy (newname + MAX_LABEL_LENGTH - suffix_length,
480 name + len - suffix_length,
481 suffix_length);
482 strncpy (newname + final_len, "_h", 2);
483 strncpy (newname + final_len + 2 , crc_chars, 5);
484 strncpy (newname + final_len + 2 + 5, encode_16 (len), 3);
485 strncpy (newname + final_len + 2 + 5 + 3, encode_16 (sum), 3);
486 if (!is_truncated_identifier (newname))
487 abort ();
488 return newname;
489 }
490
491 /* Determine whether or not ID is a truncated identifier, and return a
492 non-zero value if it is. */
493
494 static int
495 is_truncated_identifier (char *id)
496 {
497 char *ptr;
498 int len = strlen (id);
499 /* If it's not exactly MAX_LABEL_LENGTH characters long, it can't be
500 a truncated identifier. */
501 if (len != MAX_LABEL_LENGTH)
502 return 0;
503
504 /* Start scanning backwards for a _h. */
505 len = len - 3 - 3 - 5 - 2;
506 ptr = id + len;
507 while (ptr >= id)
508 {
509 if (ptr[0] == '_' && ptr[1] == 'h')
510 {
511 /* Now see if the sum encoded in the identifer matches. */
512 int x, sum;
513 sum = 0;
514 for (x = 0; x < 5; x++)
515 sum += ptr[x + 2];
516 /* If it matches, this is probably a truncated identifier. */
517 if (sum == decode_16 (ptr + 5 + 2 + 3))
518 return 1;
519 }
520 ptr--;
521 }
522 return 0;
523 }
524
525 /* end of obj-evax.c */
This page took 0.040831 seconds and 4 git commands to generate.