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