Changeset 534
- Timestamp:
- Aug 5, 2003, 8:54:32 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified trunk/src/emx/src/emxexp/emxexp.c ¶
-
Property cvs2svn:cvs-rev
changed from
1.10
to1.11
r533 r534 38 38 }; 39 39 40 /* if != 0 we're supposed to add ordinals to the symbols. */ 40 41 static int ordinal = 0; 42 /* if set the ordinals is to be sequentially assigned with no 43 conveniency gaps or anything. */ 44 static int ordinal_seq = FALSE; 41 45 static int noname_flag = FALSE; 42 46 static int bss_flag = FALSE; 43 47 static int weak_flag = FALSE; 48 /* When clear we'll do sorting and handle make sure there no duplicate weak 49 names and such. If set we'll just dump the publics and comdefs as we 50 used to do. */ 51 static int legacy_mode = FALSE; 44 52 45 53 static FILE *out_file; … … 50 58 static struct bss_list *bss_list = NULL; 51 59 60 /* OMF globals */ 61 static struct segdef 62 { 63 /* pointer to local name */ 64 const char *name; 65 } *segdefs; 66 static unsigned num_segdefs; 67 static char ** lnames; 68 static unsigned num_lnames; 69 70 /* Aout globals */ 71 static char *aout_segnames[] = 72 { 73 NULL, NULL, /* 0 N_UNDF */ 74 NULL, NULL, /* 2 N_ABS */ 75 "TEXT32", "TEXT32", /* 4 N_TEXT */ 76 "DATA32", "DATA32", /* 6 N_DATA */ 77 "BSS32", "BSS32", /* 8 N_BSS */ 78 NULL, NULL, /* a */ 79 NULL, NULL, /* c, d N_WEAKU */ 80 NULL, "TEXT32", /* d N_WEAKA, f N_WEAKT */ 81 "DATA32", "BSS32", /* 10 N_WEAKD, 11 N_WEAKB */ 82 NULL, NULL, NULL, NULL, NULL 83 }; 84 85 /* Per segment name sorting 86 Symbols are orginized in two constructs. One is a global symbol name 87 string pool kind thing. The other is per segment. 88 89 Weak symbols and communial data may be overridden. In those cases we'll 90 unlink the symbol and reinstert it to ensure that we don't get it in the 91 wrong segment. 92 */ 93 94 /* module in which a symbol is defined. */ 95 struct new_module 96 { 97 char * name; /* module name. */ 98 struct new_module * next; /* next module in the chain. */ 99 }; 100 101 /* LIFO of modules. (only so we can free it) 102 The head module is the current one. */ 103 struct new_module *new_modules; 104 105 106 /* one symbol */ 107 struct new_symbol 108 { 109 char * name; /* Symbol name from heap. */ 110 struct new_symbol *nexthash; /* Next hash table entry. */ 111 struct new_symbol *next, *prev; /* Per segment chain. */ 112 struct new_module *mod; /* Module in which the symbol is defined. */ 113 unsigned fweak:1; /* Weak symbol. */ 114 unsigned fcomm:1; /* Communial data. */ 115 unsigned fdummy:1; /* Dummy node, the one which is first & last 116 in the lists to save use from any 117 unpleasant list head/tail thinking. */ 118 }; 119 120 /* List of segments. */ 121 static struct new_symgrp 122 { 123 char * name; /* segment name */ 124 struct new_symbol *head; /* head of list. Always starts with a dummy node. */ 125 struct new_symbol *tail; /* tail of list. Always starts with a dummy node. */ 126 struct new_symgrp *next; /* next segement. */ 127 } * new_symgrps; 128 129 /* symbol string hash table */ 130 struct new_symbol * new_hashtable[211]; 131 132 133 52 134 static void error (const char *fmt, ...) NORETURN2; 53 135 static void usage (void) NORETURN2; … … 75 157 76 158 p = malloc (n); 77 if (p == NULL )159 if (p == NULL && n) 78 160 error ("Out of memory"); 79 161 return p; … … 90 172 91 173 p = realloc (ptr, n); 92 if (p == NULL )174 if (p == NULL && n) 93 175 error ("Out of memory"); 94 176 return p; 95 177 } 178 179 180 /* Create a duplicate of the string S on the heap. Quit on failure. 181 This function is used like strdup(), but we don't have to check the 182 return value. */ 183 184 char *xstrdup (const char *s) 185 { 186 char *p; 187 188 p = xmalloc (strlen (s) + 1); 189 strcpy (p, s); 190 return p; 191 } 192 96 193 97 194 … … 106 203 " -o Output ordinal numbers, starting at 1\n" 107 204 " -o<ordinal> Output ordinal numbers, starting at <ordinal>\n" 108 " -u Also export uninitialized variables\n" 109 " -w Allow export of weak symbols\n", 205 " -u Also export uninitialized variables - only legacy mode\n" 206 " -w Allow export of weak symbols - only legacy mode\n" 207 " -l Legacy mode - disables sorting and weak handling\n", 110 208 stderr); 111 209 exit (1); 210 } 211 212 213 /* New export function. This will filter out duplicated BSS32 and weak 214 symbols and insert the symbols into arrays according to segment 215 value. new_print() will be called when all the input files are 216 processed and do the actual printing and ordinal assignments. */ 217 218 static void new_export (const char *name, const char *segname, int fweak, int fcomm) 219 { 220 struct new_symbol *psym; 221 unsigned uhash; 222 const char * psz; 223 224 /* compute hash */ 225 for (uhash = 0, psz = name; *psz; *psz++) 226 uhash = uhash * 65599 + *psz; 227 uhash %= sizeof(new_hashtable) / sizeof(new_hashtable[0]); 228 229 /* look for it */ 230 for (psym = new_hashtable[uhash]; psym; psym = psym->nexthash) 231 if (!strcmp(psym->name, name)) 232 break; 233 234 /* new */ 235 if (!psym) 236 { 237 /* create new symbol node */ 238 psym = xmalloc(sizeof(*psym)); 239 psym->name = xstrdup(name); 240 241 /* insert into hash */ 242 psym->nexthash = new_hashtable[uhash]; 243 new_hashtable[uhash] = psym; 244 } 245 else 246 {/* existing. look for overrided symbols (weak/comm) and ignore duplicates. */ 247 if (fweak || fcomm) 248 psym = NULL; /* just skip it - did I forget something...? */ 249 else 250 { 251 if (psym->fcomm || psym->fweak) 252 { /* unlink the symbol. */ 253 psym->prev->next = psym->next; 254 psym->next->prev = psym->prev; 255 } 256 else 257 psym = NULL; 258 } 259 } 260 261 /* insert the correct list */ 262 if (psym) 263 { 264 struct new_symgrp *psymgrp; 265 266 /* Set symbol data */ 267 psym->fcomm = fcomm; 268 psym->fweak = fweak; 269 psym->fdummy = 0; 270 psym->mod = new_modules; 271 272 273 /* find the segment */ 274 for (psymgrp = new_symgrps; psymgrp; psymgrp = psymgrp->next) 275 if ( psymgrp->name == segname 276 || (segname && psymgrp->name && !strcmp(psymgrp->name, segname)) 277 ) 278 break; 279 280 /* new or old ? */ 281 if (!psymgrp) 282 { 283 psymgrp = xmalloc(sizeof(*psymgrp)); 284 psymgrp->name = segname ? xstrdup(segname) : NULL; 285 psymgrp->head = xmalloc(sizeof(*psymgrp->head)); 286 psymgrp->tail = xmalloc(sizeof(*psymgrp->tail)); 287 memset(psymgrp->head, 0, sizeof(*psymgrp->head)); 288 memset(psymgrp->tail, 0, sizeof(*psymgrp->tail)); 289 psymgrp->head->fdummy = 1; 290 psymgrp->tail->fdummy = 1; 291 /* link dummies */ 292 psymgrp->head->next = psymgrp->tail; 293 psymgrp->tail->prev = psymgrp->head; 294 psymgrp->head->name = psymgrp->tail->name = "#;$$$$$$dummy$$$$$$$$$$$;#"; 295 /* link it in */ 296 psymgrp->next = new_symgrps; 297 new_symgrps = psymgrp; 298 } 299 300 /* insert at tail. */ 301 psym->prev = psymgrp->tail->prev; 302 psym->next = psymgrp->tail; 303 psymgrp->tail->prev->next = psym; 304 psymgrp->tail->prev = psym; 305 } 306 } 307 308 309 /* Print the publics. (new method) 310 311 When -o is not specified with number, to leave a round number of unused 312 ordinals between the segments out of convenience mostly. */ 313 314 static void new_print(FILE *phfile, struct new_symgrp *psymgrp) 315 { 316 /* enumerate symbol groups (segments) */ 317 for (; psymgrp; psymgrp = psymgrp->next) 318 { 319 struct new_symbol *psym; 320 321 /* print a decent header */ 322 if (psymgrp->name) 323 fprintf (phfile, " ; segment %s\n", psymgrp->name); 324 else 325 fprintf (phfile, " ; segment noname\n"); 326 327 /* enumerate symbols */ 328 for (psym = psymgrp->head->next; psym != psymgrp->tail; psym = psym->next) 329 { 330 int cch; 331 332 cch = fprintf (phfile, " \"%s\"", psym->name); 333 /* fancy align */ 334 if (cch < 69) 335 cch = 70 - cch; 336 else if (cch < 89) 337 cch = 90 - cch; 338 else if (cch < 119) 339 cch = 120 - cch; 340 else 341 cch = 40 - (cch % 39); 342 fprintf (phfile, "%*s", cch, ""); 343 344 /* flags */ 345 if (ordinal != 0) 346 cch += fprintf (phfile, " @%-5d", ordinal++); 347 if (noname_flag) 348 cch += fprintf (phfile, " NONAME"); 349 350 /* comments - the first one might be used by emximp later... */ 351 fprintf (phfile, " ; magicseg='%s' len=%d", 352 psymgrp->name ? psymgrp->name : "", strlen(psym->name)); 353 if (psym->fweak) 354 fprintf (phfile, " weak"); 355 if (psym->fcomm) 356 fprintf (phfile, " comm"); 357 if (psym->mod) 358 fprintf (phfile, " mod='%s'", psym->mod->name); 359 360 fputc ('\n', phfile); 361 } 362 363 /* skip a line and some ordinals if we're allowed */ 364 fputc ('\n', phfile); 365 if (!ordinal_seq) 366 ordinal = ((ordinal + 199) / 100) * 100; 367 } 112 368 } 113 369 … … 200 456 if (sym_ptr[i].n_type == (N_TEXT|N_EXT) || 201 457 sym_ptr[i].n_type == (N_DATA|N_EXT) || 202 ( weak_flag&&458 ((!legacy_mode || weak_flag) && 203 459 (sym_ptr[i].n_type == N_WEAKT || 204 460 sym_ptr[i].n_type == N_WEAKD))) 205 461 { 206 462 name = str_ptr + sym_ptr[i].n_un.n_strx; 207 export (name); 463 if (legacy_mode) 464 export (name); 465 else 466 new_export (name, aout_segnames[sym_ptr[i].n_type], 467 sym_ptr[i].n_type >= N_WEAKU && sym_ptr[i].n_type >= N_WEAKB, 468 FALSE); 208 469 } 209 470 else if ((sym_ptr[i].n_type == N_EXT && sym_ptr[i].n_value != 0) || 210 471 sym_ptr[i].n_type == (N_BSS|N_EXT) || 211 ( weak_flag&& sym_ptr[i].n_type == N_WEAKB))472 ((!legacy_mode || weak_flag) && sym_ptr[i].n_type == N_WEAKB)) 212 473 { 213 474 name = str_ptr + sym_ptr[i].n_un.n_strx; 214 export_bss (name); 475 if (legacy_mode) 476 export_bss (name); 477 else 478 new_export (name, aout_segnames[sym_ptr[i].n_type], 479 sym_ptr[i].n_type >= N_WEAKU && sym_ptr[i].n_type >= N_WEAKB, 480 TRUE); 215 481 } 216 482 … … 334 600 word frame; 335 601 dword offset; 336 byte name[2 56];602 byte name[260]; 337 603 338 604 group = get_index (); … … 343 609 while (rec_idx < rec_len) 344 610 { 611 char *weak; 345 612 get_string (name); 346 613 offset = get_word_or_dword (); 347 614 type = get_index (); 348 export (name); 615 weak = strstr(name, "$w$"); 616 if (legacy_mode) 617 { 618 if (!weak || weak_flag) 619 export (name); 620 } 621 else 622 { 623 if (weak) 624 { 625 memmove(weak + 1, weak, strlen(weak) + 1); 626 *weak++ = '\0'; 627 } 628 new_export (name, segdefs[seg].name, weak != NULL, FALSE); 629 } 349 630 } 350 631 } … … 354 635 { 355 636 int type_index, data_type; 356 byte name[2 56];637 byte name[260]; 357 638 358 639 while (rec_idx < rec_len) 359 640 { 641 char *weak; 360 642 get_string (name); 361 643 type_index = get_index (); … … 373 655 bad_omf (); 374 656 } 375 export_bss (name); 376 } 377 } 657 658 weak = strstr(name, "$w$"); 659 if (legacy_mode) 660 { 661 if (!weak || weak_flag) 662 export_bss (name); 663 } 664 else 665 { 666 if (weak) 667 { 668 memmove(weak + 1, weak, strlen(weak) + 1); 669 *weak++ = '\0'; 670 } 671 new_export (name, "BSS32", weak != NULL, TRUE); 672 } 673 } 674 } 675 676 677 static void omf_lnames (void) 678 { 679 while (rec_idx < rec_len) 680 { 681 unsigned len = get_byte (); 682 if (!(num_lnames % 64)) 683 lnames = xrealloc(lnames, sizeof(lnames[0]) * (num_lnames + 64)); 684 lnames[num_lnames] = xmalloc(len + 1); 685 get_mem(lnames[num_lnames], len); 686 lnames[num_lnames][len] = '\0'; 687 num_lnames++; 688 } 689 } 690 691 692 static void omf_segdef (void) 693 { 694 byte flags; 695 unsigned nameidx; 696 unsigned classidx; 697 unsigned ovlidx; 698 699 /* all we want the the segment name */ 700 flags = get_byte (); /* segment attributes */ 701 if ((flags & 0xE0) == 0) 702 { 703 get_word (); /* frame number */ 704 get_byte (); /* offset */ 705 } 706 if (rec_type & REC32) /* segment length */ 707 get_dword (); 708 else 709 get_word (); 710 711 nameidx = get_index (); 712 classidx = get_index (); 713 ovlidx = get_index (); 714 if (nameidx == 0) 715 nameidx = classidx; /* paranoia */ 716 717 /* add it */ 718 if (!(num_segdefs % 64)) 719 segdefs = xrealloc (segdefs, sizeof(segdefs[0]) * (num_segdefs + 64)); 720 if (nameidx != 0 && nameidx < num_lnames) 721 segdefs[num_segdefs].name = lnames[nameidx]; 722 else 723 segdefs[num_segdefs].name = NULL; 724 num_segdefs++; 725 } 726 378 727 379 728 380 729 static void process_omf (FILE *inp_file) 381 730 { 382 struct omf_rec rec; 383 731 int i; 732 struct omf_rec rec; 733 734 /* init */ 384 735 new_mod = TRUE; 736 lnames = xmalloc(sizeof(lnames[0])* 64); 737 lnames[0] = NULL; 738 num_lnames = 1; /* dummy entry */ 739 segdefs = xmalloc(sizeof(segdefs[0])* 64); 740 memset(&segdefs[0], 0, sizeof(segdefs[0])); 741 num_segdefs = 1; 742 743 /* read */ 385 744 do 386 745 { … … 402 761 break; 403 762 case COMDEF: 404 if ( bss_flag)763 if (!legacy_mode || bss_flag) 405 764 omf_comdef (); 406 765 break; 766 case LNAMES: 767 omf_lnames (); 768 break; 769 case SEGDEF: 770 case SEGDEF|REC32: 771 omf_segdef (); 772 break; 407 773 } 408 774 } while (rec.rec_type != MODEND && rec_type != (MODEND|REC32)); 775 776 /* cleanup (entry 0 isn't used) */ 777 for (i = 1; i < num_lnames; i++) 778 free(lnames[i]); 779 free(lnames); 780 free(segdefs); 409 781 } 410 782 … … 593 965 case 'o': 594 966 if (optarg == NULL) 595 ordinal = 1;967 ordinal = 1; 596 968 else 597 969 { … … 601 973 || ordinal < 1 || ordinal > 65535) 602 974 usage (); 975 ordinal_seq = 1; 603 976 } 604 977 break; … … 609 982 weak_flag = TRUE; 610 983 break; 984 case 'l': 985 legacy_mode = TRUE; 986 break; 611 987 default: 612 988 error ("Invalid option"); … … 625 1001 } 626 1002 1003 if (!legacy_mode) 1004 new_print(out_file, new_symgrps); 1005 627 1006 if (fflush (out_file) != 0 || (out_file != stdout && fclose (out_file) != 0)) 628 1007 error ("Write error"); -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.