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 */ 526