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