Changeset 491
- Timestamp:
- Aug 1, 2003, 3:44:05 AM (22 years ago)
- Location:
- trunk/src/emx/src/emxomf
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/emx/src/emxomf/weakld.c
-
Property cvs2svn:cvs-rev
changed from
1.3
to1.4
r490 r491 25 25 26 26 /** @page weakld Weak Pre-Linker 27 * 27 * 28 28 * In order to get the weak symbols somewhat right it looks like we have to do 29 29 * the pass1 of the linking process in order to resolve the weak symbols. … … 33 33 * @subsection Symbols 34 34 * 35 * There is a couple of symbol types, but we can skip most of them for this 35 * There is a couple of symbol types, but we can skip most of them for this 36 36 * pre-linking operation. We use one symbol type which is public or global 37 37 * symbols if you like. Perhaps it would be wise to devide them into separat … … 48 48 #define OMF_MAX_REC 1024 49 49 50 /** helper to make verbose only output. */ 51 #define WLDINFO(pWld, a) do { if (pWld->fFlags & WLDC_VERBOSE) wldInfo a; } while (0) 52 53 /** Internal error */ 54 #define WLDINTERR(pWld, pMod) wldIntErr(pWld, pMod, __FILE__, __LINE__, __FUNCTION__); 55 56 57 /** Helpers for checking if a symbol is defined strongly. */ 58 #define SYM_IS_DEFINED(fFlags) ( (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_PUBLIC \ 59 || (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_COMM \ 60 || (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_IMPORT \ 61 ) 62 /** Helpers for checking if a symbol is strongly undefined. No weaks included! */ 63 #define SYM_IS_UNDEFINED(fFlags) ( (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF) 64 65 50 66 51 67 /******************************************************************************* … … 53 69 *******************************************************************************/ 54 70 #include <stdio.h> 71 #include <stdlib.h> 72 #include <stdarg.h> 55 73 #include <string.h> 56 #include <stdlib.h>57 74 #include <sys/types.h> 58 75 #include <sys/omflib.h> … … 61 78 #include "weakld.h" 62 79 63 80 64 81 /******************************************************************************* 65 82 * Structures and Typedefs * 66 83 *******************************************************************************/ 67 84 /** 68 * Library structure 85 * Library structure 69 86 */ 70 87 typedef struct wldlib … … 77 94 struct wldlib * pNext; 78 95 } WLDLIB, *PWLDLIB; 79 80 81 /** 82 * Module structure 83 */ 96 97 98 /** 99 * Module structure 100 */ 84 101 typedef struct wldmod 85 102 { … … 95 112 struct wldmod *pNext; 96 113 } WLDMOD, *PWLDMOD; 97 114 98 115 99 116 /** … … 107 124 const char * pszWeakName; 108 125 109 /** Symbol type. */110 enum {111 WLDST_PUBLIC112 } eType;113 114 126 /** Symbol flags. */ 115 127 enum { 116 /** @group Symbol state128 /** @group Symbol Type 117 129 * @{ */ 118 /* Mask of the symbol state. */119 WLDSF_ STATEMASK= 0x000f,130 /* Mask of the symbol type. */ 131 WLDSF_TYPEMASK = 0x000f, 120 132 /** Strong symbol. 121 133 * A strong definition exists for this symbol (PUBDEF). */ 122 WLDSF_ STRONG= 0x0001,123 /** Communal data/code. 134 WLDSF_PUBLIC = 0x0001, 135 /** Communal data/code. 124 136 * Communal definition exists for this symbol. 125 137 * If a PUBDEF is found for this symbol it will become strong. */ 126 138 WLDSF_COMM = 0x0002, 139 /** Imported symbol. 140 * This symbol is imported. 141 * Note that when combined with WLDSF_LIBSEARCH a symbol in this type 142 * will yield to stronger definitions with a little warning. */ 143 WLDSF_IMPORT = 0x0003, 127 144 /** Undefined symbol. 128 145 * This symbol is not yet defined anywhere. */ 129 WLDSF_UNDEF = 0x000 3,146 WLDSF_UNDEF = 0x0004, 130 147 /** Weak external. 131 148 * This symbol doesn't need to be resolved as it have a default … … 134 151 * WLDSF_UNDEF. 135 152 */ 136 WLDSF_WKEXT = 0x000 4,153 WLDSF_WKEXT = 0x0005, 137 154 /** @} */ 138 155 139 /** Weak symbol. 140 * This symbol doesn't need to be resolved (if WLDSF_UNDEF), or 156 /** Uncertain undefined symbol. 157 * We're still processing the module containing this and the uncertainty 158 * we're facing is that a WLDSF_UNDEF may changed to an WLDSF_WKEXT 159 * upon encountering a WKEXT COMENT record. */ 160 WLDSF_UNCERTAIN = 0x0100, 161 162 /** Symbol found during library search. 163 * If this is an attribute to a symbol of the WLDSF_IMPORT type, the 164 * symbol is actually kind of weak. 165 */ 166 WLDSF_LIBSEARCH = 0x0200, 167 168 /** Weak symbol. 169 * This symbol doesn't need to be resolved (if WLDSF_UNDEF), or 141 170 * it may be overridden by a EXTDEF with no WKEXT. 142 171 * If this is an weak undefined symbol (extern weak, local default) 143 172 * pWeakDefault Will point at it. 144 173 */ 145 WLDSF_WEAK = 0x0100, 146 147 /** Uncertain undefined symbol. 148 * We're still processing the module containing this and the uncertainty 149 * we're facing is that a WLDSF_UNDEF may changed to an WLDSF_WKEXT 150 * upon encountering a WKEXT COMENT record. */ 151 WLDSF_UNCERTAIN = 0x0200, 152 153 154 /** Import symbol. 155 * This symbol is imported. */ 156 WLDSF_IMPORT = 0x0400, 157 /** Exported symbol. 158 * This symbol is to be exported. */ 159 WLDSF_EXPORT = 0x0800, 174 WLDSF_WEAK = 0x0400, 175 160 176 /** Alias symbol. 161 177 * This symbol is an alias for another symbol. pAliasFor will be set. */ 162 WLDSF_ALIAS = 0x1000, 163 } eFlags; 178 WLDSF_ALIAS = 0x0800, 179 180 /** Exported symbol. 181 * This symbol is to be exported. */ 182 WLDSF_EXPORT = 0x1000, 183 184 } fFlags; 164 185 165 186 /** The module this symbol is defined in. */ 166 187 PWLDMOD pMod; 167 188 168 169 /** Import module - only if WLDSF_IMPORT is set. */ 189 /** @group Import Attributes 190 * Valid when type is WLDSF_IMPORT. 191 * @{ */ 192 /** Import module. */ 170 193 const char* pszImpMod; 171 172 /** Import Ordinal (WLDSF_IMPORT). 194 /** Import Ordinal (WLDSF_IMPORT). 173 195 * 0 means no ordinal. */ 174 unsigned iImpOrd; 175 176 177 /** Export flags */ 178 struct 179 { 180 unsigned fResidentName : 1; /* Put name in resident or non resident table. */ 181 unsigned fNoName : 1; /* No name at all. */ 182 unsigned fNoData : 1; /* ?? */ 183 unsigned cParams; /* callgate stuff, # of words to push */ 184 } fExport; 185 186 /** Import Ordinal (WLDSF_EXPORT). 187 * 0 means no ordinal. */ 188 unsigned iExpOrd; 189 190 191 /** Symbol this is an alias for. */ 192 struct wldsym * pAliasFor; 193 194 /** Weak default resolution. 195 * If this symbol in state WLDSF_WKEXT or have to WLDSF_WEAK flag set this 196 * member indicates a default resolution for the symbol. For WLDSF_WEAK 197 * this only make sense if the state is WLDSF_UNDEF. 196 unsigned uImpOrd; 197 /** @} */ 198 199 /** Weak default resolution. 200 * Valid if the symbol is of type WLDSF_WKEXT or have the WLDSF_WEAK flag set. 201 * Indicates a default resolution for the symbol. 202 * For WLDSF_WEAK this only make sense if the type is WLDSF_UNDEF. 198 203 */ 199 204 struct wldsym * pWeakDefault; 205 206 /** Symbol this is an alias for. 207 * Valid when WLDSF_ALIAS is set. */ 208 struct wldsym * pAliasFor; 209 210 /** @group Export Attributes 211 * Valid when WLDSF_EXPORT is set. 212 * @{ */ 213 /** Export flags. */ 214 enum 215 { 216 /** @group Name */ 217 /** Name type mask. */ 218 WLDSEF_NAMEMASK = 0x03, 219 /** Default action depending on if it have an ordinal or not. 220 * If it have an ordinal it shall be non-resident, if it hasn't 221 * it shall be resident. 222 */ 223 WLDSEF_DEFAULT = 0x00, 224 /** The name shall be in the resident nametable. */ 225 WLDSEF_RESIDENT = 0x01, 226 /** The name shall be in the resident nametable. */ 227 WLDSEF_NONRESIDENT = 0x02, 228 /** The export shall only have ordinal. */ 229 WLDSEF_NONAME = 0x03, 230 /** @} */ 231 /** no idea what this implies */ 232 WLDSEF_NODATA = 0x04 233 } fExport; 234 /** Export word count. */ 235 unsigned cExpWords; 236 /** Export Ordinal. 237 * 0 means no ordinal. */ 238 unsigned uExpOrd; 239 /** @} */ 200 240 201 241 /** Next node in the hash bucket. */ … … 212 252 } WLDSYMTAB, *PWLDSYMTAB; 213 253 214 215 /** 254 255 /** 216 256 * Weak Pre-Linker Instance. 217 257 */ … … 236 276 }; 237 277 typedef struct wld WLD; 238 239 240 /** @group OMF stuff 278 279 /** symAdd Action. */ 280 typedef enum { WLDSA_NEW, WLDSA_UP, WLDSA_OLD, WLDSA_ERR } WLDSYMACTION, *PWLDSYMACTION; 281 282 283 /** @group OMF stuff 241 284 * @{ */ 242 285 … … 269 312 extern void *xmalloc (size_t n); 270 313 271 static unsigned hash(const char* pszSym, unsigned cch); 314 static void wldInfo(const char *pszFormat, ...); 315 static void wldIntErr(PWLD pWld, PWLDMOD pMod, const char *pszFile, unsigned iLine, const char *pszFunction); 316 static int modError(PWLDMOD pMod, const char *pszFormat, ...); 317 static void modWarn(PWLDMOD pMod, const char *pszFormat, ...); 272 318 static FILE * modOpen(PWLDMOD pMod); 273 319 static void modClose(PWLDMOD pMod); 274 320 321 static inline unsigned hash(const char* pszSym, unsigned cch); 322 static PWLDSYM symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, 323 unsigned long ulValue, unsigned iSegment, PWLDSYMACTION peAction); 275 324 276 325 277 326 /******************************************************************************* 278 * 327 * 279 328 * H e l p e r s 280 329 * H e l p e r s 281 330 * H e l p e r s 282 * 331 * 283 332 *******************************************************************************/ 284 333 285 /** 286 * Calculate the hash value of a symbol. 287 * @returns hash value. 288 * @param pszSym Symbol to calculate it for. 289 * @param cch Symbol length. 290 */ 291 static unsigned hash(const char* pszSym, unsigned cch) 292 { 293 unsigned uHash = 0; 294 while (cch && *pszSym && *pszSym != '$') 295 { 296 uHash = uHash * 65599 + *pszSym; 297 pszSym++; 298 cch--; 299 } 300 uHash %= WLDSYM_HASH_SIZE; 301 return uHash; 302 } 334 335 /** 336 * Put out a info message. 337 * @param pszFormat Format string. 338 * @param ... Format arguments. 339 */ 340 static void wldInfo(const char *pszFormat, ...) 341 { 342 va_list args; 343 fprintf(stderr, "weakld: info: "); 344 345 va_start(args, pszFormat); 346 vfprintf(stderr, pszFormat, args); 347 va_end(args); 348 if (pszFormat[strlen(pszFormat) - 1] != '\n') 349 fputc('\n', stderr); 350 } 351 352 353 /** 354 * Internal error. 355 * 356 * @returns don't return, it aborts the process. 357 * @param pWld Pointer to linker instance (optional). 358 * @param pMod Pointe to module (optional). 359 * @param pszFile File name of the error. 360 * @param iLine Line number of the error. 361 * @param pszFunction The function in which the error occured. 362 */ 363 static void wldIntErr(PWLD pWld, PWLDMOD pMod, const char *pszFile, unsigned iLine, const char *pszFunction) 364 { 365 fprintf(stderr, "\nweakld: "); 366 if (pMod) 367 { 368 if (pMod->pLib) 369 fprintf(stderr, "%s(%s) ", pMod->pLib->pszLibName, pMod->pszModName); 370 else 371 fprintf(stderr, "%s ", pMod->pszModName); 372 } 373 fprintf(stderr, "internal error!"); 374 fprintf(stderr, "file: %s line: %d function: %s\n", pszFile, iLine, pszFunction); 375 abort(); 376 } 377 303 378 304 379 /** … … 308 383 * @param ... Format arguments. 309 384 */ 310 static voidmodError(PWLDMOD pMod, const char *pszFormat, ...)385 static int modError(PWLDMOD pMod, const char *pszFormat, ...) 311 386 { 312 387 va_list args; … … 321 396 if (pszFormat[strlen(pszFormat) - 1] != '\n') 322 397 fputc('\n', stderr); 398 return -1; 323 399 } 324 400 … … 379 455 /* Position the stream at the start of the module. */ 380 456 if (!pMod->phFile) 381 modErr ro(pMod, "failed to reopen.");457 modError(pMod, "failed to reopen."); 382 458 else 383 459 { 384 460 if (fseek(pMod->phFile, pMod->off, SEEK_SET)) 385 461 { 386 modErr ro(pMod, "failed to seek to module start (%#x).", pMod->off);462 modError(pMod, "failed to seek to module start (%#x).", pMod->off); 387 463 modClose(pMod); 388 464 return NULL; 389 465 } 390 466 } 391 467 392 468 return pMod->phFile; 393 469 } … … 409 485 410 486 487 488 489 490 /** 491 * Calculate the hash value of a symbol. 492 * @returns hash value. 493 * @param pszSym Symbol to calculate it for. 494 * @param cch Symbol length. 495 */ 496 static inline unsigned hash(const char* pszSym, unsigned cch) 497 { 498 unsigned uHash = 0; 499 while (cch && *pszSym && *pszSym != '$') 500 { 501 uHash = uHash * 65599 + *pszSym; 502 pszSym++; 503 cch--; 504 } 505 uHash %= WLDSYM_HASH_SIZE; 506 return uHash; 507 } 508 509 /** 510 * Adds a symbol. 511 * 512 * Actually if the symbol exists we'll perform any required symbol 'merger' and 513 * either fail due to symbol errors or return the 'merged' one. 514 * 515 * We'll simply return existing symbol when: 516 * 1. adding a UNDEF where a PUBLIC or COMM exists. 517 * 2. adding a WKEXT where a PUBLIC or COMM exists. 518 * 3. adding a WKEXT where a UNDEF which isn't UNCERTAIN exists. 519 * 4. adding a COMM where a !WEAK COMM exists. (todo value check) 520 * 5. adding a WEAK PUBLIC or WEAK COMM where a PUBLIC or COMM exists. 521 * 522 * We'll warn and return existing symbol when: 523 * 1. adding a IMPORT LIBSEARCH where a PUBLIC or COMM exists. 524 * 525 * We'll return upgraded existing symbol when: 526 * 1. adding a PUBLIC or COMM where a UNDEF or WKEXT exists. 527 * 2. adding a !WEAK PUBLIC or !WEAK COMM where a WEAK PUBLIC or WEAK COMM exists. 528 * 3. adding a !WEAK UNDEF where a WEAK UNDEF exists. 529 * 4. adding a UNDEF where a WKEXT exists. 530 * 531 * We'll warn and upgraded existing symbol when: 532 * 1. adding a PUBLIC or COMM where a IMPORT LIBSEARCH exists. 533 * 534 * The rest is failures. 535 * 536 * There migth be errors in the algorithm. Like adding the same import twice 537 * shouldn't harm anybody, but it's unlikely and it requires quite some extra parameters. 538 * Also the caller must resolve any conflicting exports (which normally only yields 539 * warnings anyway it seems). 540 * 541 * @returns Pointer to symbold. 542 * @returns NULL on failure. 543 * @param pWld Linker instance. 544 * @param pMod Module the the symbol is defined in. 545 * @param fFlags Symbol flags. 546 * All the flags in WLDSF_TYPEMASK, WLDSF_WEAK and WLDSF_LIBSEARCH. 547 * WLDSF_EXPORT isn't handled and should not be defined. 548 * WLDSF_ALIAS and WLDSF_UNCERTAIN is ignored as they have no 549 * sideeffects when resolving symbols. 550 * @param pachName Pointer to symbol name. 551 * @param cchName Length to add, use -1 if zeroterminated. 552 * @param ulValue Value of the symbol (if it's relevant for this kind of symbol). (ignored) 553 * @param iSegment Segment of pMod in which this symbol is defined (only if relevant). (ignored) 554 * @param pflAction What we actually did. 555 * WLDSA_NEW, WLDSA_UP, WLDSA_OLD, WLDSA_ERR. 556 */ 557 static PWLDSYM symAdd(PWLD pWld, PWLDMOD pMod, unsigned fFlags, const char *pachName, int cchName, 558 unsigned long ulValue, unsigned iSegment, PWLDSYMACTION peAction) 559 { 560 PWLDSYM pSym; /* The symbol. */ 561 unsigned uHash; /* The symbol name hash. */ 562 const char *pszName; /* The symbol name in the string pool */ 563 int cchNameWeak = 0; /* Indicator and length of the weak name. (0 if not weak) */ 564 /* general stuff */ 565 const char * pach; 566 567 if (peAction) 568 *peAction = WLDSA_ERR; 569 if (cchName < 0) 570 cchName = strlen(pachName); 571 572 /* adjust namelength / check for weak name / hash name */ 573 pach = pachName + cchName - 2; /* "$w$" */ 574 while (pach-- > pachName) 575 if ( pach[0] == '$' 576 && pach[1] == 'w' 577 && pach[2] == '$') 578 { 579 cchNameWeak = cchName; 580 cchName = pachName - pach; 581 fFlags |= WLDSF_WEAK; 582 /* If WKEXT we'll upgrade it to weak undefined. (yeah, big deal?) */ 583 if ((fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT) 584 fFlags = (fFlags & ~WLDSF_TYPEMASK) | WLDSF_UNDEF; 585 break; 586 } 587 uHash = hash(pachName, cchName); 588 pszName = (pWld->fFlags & WLDC_CASE_INSENSITIVE ? strpool_addn : strpool_addnu)(pWld->pStrMisc, pachName, cchName); 589 590 /* search for existing symbol */ 591 pSym = pWld->Global.ap[uHash]; 592 while (pSym && pSym->pszName == pszName) 593 pSym = pSym->pHashNext; 594 595 if (!pSym) 596 { 597 /* 598 * new symol - this is easy! 599 */ 600 pSym = xmalloc(sizeof(*pSym)); 601 memset(pSym, 0, sizeof(*pSym)); 602 pSym->fFlags = fFlags; 603 pSym->pszName = pszName; 604 if (SYM_IS_DEFINED(pSym->fFlags)) 605 pSym->pMod = pMod; 606 if (cchNameWeak) 607 { 608 pSym->pszWeakName = strpool_addn(pWld->pStrMisc, pachName, cchNameWeak); 609 pSym->fFlags |= WLDSF_WEAK; 610 WLDINFO(pWld, ("Weak symbol '%s'.", pSym->pszWeakName)); 611 } 612 pSym->pHashNext = pWld->Global.ap[uHash]; 613 pWld->Global.ap[uHash] = pSym; 614 if (peAction) *peAction = WLDSA_NEW; 615 } 616 else 617 { /* found existing symbol - more complex... */ 618 619 /* 620 * We'll simply return existing symbol when: 621 * 1. adding a UNDEF where a PUBLIC or COMM exists. 622 * 2. adding a WKEXT where a PUBLIC or COMM exists. 623 * 3. adding a WKEXT where a UNDEF which isn't UNCERTAIN exists. 624 * 4. adding a COMM where a !WEAK COMM exists. (todo value check) 625 * 5. adding a WEAK PUBLIC or WEAK COMM where a PUBLIC or COMM exists. 626 */ 627 if ( ( /* 1 */ 628 (fFlags & WLDSF_TYPEMASK) == WLDSF_UNDEF 629 && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 630 ) || ( /* 2 */ 631 (fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT 632 && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 633 ) || ( /* 3 */ 634 (fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT 635 && (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_UNCERTAIN)) == WLDSF_UNDEF 636 ) || ( /* 4 */ 637 (fFlags & WLDSF_TYPEMASK) == WLDSF_COMM 638 && (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_COMM 639 ) || ( /* 5 */ 640 ((fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_PUBLIC | WLDSF_WEAK) || (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_COMM | WLDSF_WEAK)) 641 && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 642 )) 643 { 644 if (peAction) *peAction = WLDSA_OLD; 645 } 646 /* 647 * We'll warn and return existing symbol when: 648 * 1. adding a IMPORT LIBSEARCH where a PUBLIC or COMM exists. 649 */ 650 else 651 if ( (fFlags & (WLDSF_TYPEMASK | WLDSF_LIBSEARCH)) == (WLDSF_IMPORT | WLDSF_LIBSEARCH) 652 && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 653 ) 654 { 655 modWarn(pMod, "Ignoring import '%s' as it's defined already.", pszName); 656 if (peAction) *peAction = WLDSA_OLD; 657 } 658 /* 659 * We'll return upgraded existing symbol when: 660 * 1. adding a PUBLIC or COMM where a UNDEF or WKEXT exists. 661 * 2. adding a !WEAK PUBLIC or !WEAK COMM where a WEAK PUBLIC or WEAK COMM exists. 662 * 3. adding a !WEAK UNDEF where a WEAK UNDEF exists. 663 * 4. adding a UNDEF where a WKEXT exists. 664 */ 665 else 666 if ( ( /* 1 */ 667 ((fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 668 && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_UNDEF) 669 ) || ( /* 2 */ 670 ((fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_PUBLIC || (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_COMM) 671 && ((pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_PUBLIC | WLDSF_WEAK) || (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_COMM | WLDSF_WEAK)) 672 ) || ( /* 3 */ 673 (fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF 674 && (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == (WLDSF_UNDEF | WLDSF_WEAK) 675 ) || ( /* 4 */ 676 (fFlags & WLDSF_TYPEMASK) == WLDSF_UNDEF 677 && (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT 678 )) 679 { 680 if (!(pSym->fFlags & WLDSF_WEAK) && (fFlags & WLDSF_WEAK) && cchNameWeak) 681 { /* the symbol is upgraded to a weak one - there probably won't be a name though. */ 682 pSym->pszWeakName = strpool_addn(pWld->pStrMisc, pachName, cchNameWeak); 683 } 684 pSym->fFlags = (pSym->fFlags & ~(WLDSF_TYPEMASK | WLDSF_WEAK | WLDSF_UNCERTAIN | WLDSF_LIBSEARCH)) | fFlags; 685 if (peAction) *peAction = WLDSA_UP; 686 } 687 /* 688 * We'll warn and upgraded existing symbol when: 689 * 1. adding a PUBLIC or COMM where a IMPORT LIBSEARCH exists. 690 */ 691 else 692 if ( ((fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (fFlags & WLDSF_TYPEMASK) == WLDSF_COMM) 693 && (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_LIBSEARCH)) == (WLDSF_IMPORT | WLDSF_LIBSEARCH) 694 ) 695 { 696 modWarn(pMod, "Ignoring imported symbol '%s' as it's being defined here.", pszName); 697 698 if (!(pSym->fFlags & WLDSF_WEAK) && (fFlags & WLDSF_WEAK) && cchNameWeak) 699 { /* the symbol is upgraded to a weak one - there probably won't be a name though. */ 700 pSym->pszWeakName = strpool_addn(pWld->pStrMisc, pachName, cchNameWeak); 701 } 702 pSym->fFlags = (pSym->fFlags & ~(WLDSF_TYPEMASK | WLDSF_WEAK | WLDSF_UNCERTAIN | WLDSF_LIBSEARCH)) | fFlags; 703 if (peAction) *peAction = WLDSA_UP; 704 } 705 /* 706 * That's all, now it's just error left. 707 * 708 * (Afraid we might end up here without wanting to a few times before 709 * squashing all the bugs in the algorithm.) 710 */ 711 else 712 { 713 modError(pMod, "Duplicate symbol '%s'.", pszName); 714 if (pSym->pMod) 715 modError(pSym->pMod, "Previous symbol defined in this module."); 716 wldInfo("fFlags new 0x%04x fFlags old 0x%04x.", fFlags, pSym->fFlags); 717 pSym = NULL; 718 } 719 } 720 721 return pSym; 722 } 723 724 725 726 /** 727 * Adds an import symbol to the linking. 728 * 729 * @returns see symAdd() 730 * @param pWld Pointer to linker instance. 731 * @param pMod Pointer to module 732 * @param fLibSearch Set if we're doing library search at this time. 733 * @param pachIntName Internal name, the one which can be referenced in this module. 734 * @param cchIntName Length of that name. -1 if zero terminated string. 735 * @param pachModName Module name where the export should be resolved on load time. 736 * @param cchModName Length of that name. -1 if zero terminated string. 737 * @param uOrdinal The ordinal it's exported with from the module. 738 * 0 if exported by the name pachIntName represent. 739 */ 740 PWLDSYM symAddImport(PWLD pWld, PWLDMOD pMod, int fLibSearch, 741 const char *pachIntName, int cchIntName, 742 const char *pachModName, int cchModName, 743 unsigned uOrdinal) 744 { 745 WLDSYMACTION eAction; 746 PWLDSYM pSym; 747 const char * pszImpMod; 748 749 pSym = symAdd(pWld, pMod, WLDSF_IMPORT | (fLibSearch ? WLDSF_LIBSEARCH : 0), 750 pachIntName, cchIntName, 0, 0, &eAction); 751 if (!pSym) 752 return NULL; 753 754 pszImpMod = strpool_addnu(pWld->pStrMisc, pachModName, cchModName); 755 switch (eAction) 756 { 757 case WLDSA_NEW: 758 pSym->pszImpMod = pszImpMod; 759 pSym->uImpOrd = uOrdinal; 760 break; 761 762 case WLDSA_OLD: 763 { /* verify that the name matches */ 764 if ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_IMPORT) 765 { 766 if (!pSym->pszImpMod) 767 { 768 pSym->pszImpMod = pszImpMod; 769 pSym->uImpOrd = uOrdinal; 770 } 771 else 772 { 773 if ( pSym->pszImpMod != pszImpMod 774 && pSym->uImpOrd != uOrdinal) 775 { 776 modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s') and different ordinal (%d != %d).", 777 pSym->pszName, pSym->pszImpMod, pszImpMod, pSym->uImpOrd, uOrdinal); 778 } 779 else if (pSym->uImpOrd != uOrdinal) 780 { 781 modWarn(pMod, "Existing import '%s' have different ordinal (%d != %d).", 782 pSym->pszName, pSym->uImpOrd, uOrdinal); 783 } 784 else if (pSym->pszImpMod != pszImpMod) 785 { 786 modWarn(pMod, "Existing import '%s' have different module name than the new ('%s' != '%s').", 787 pSym->pszName, pSym->pszImpMod, pszImpMod); 788 } 789 } 790 } 791 /* else: no need to complain, symAdd already did that. */ 792 break; 793 } 794 795 case WLDSA_UP: 796 default: 797 WLDINTERR(pWld, pMod); 798 } 799 800 return pSym; 801 } 802 803 804 /** 805 * Adds(/Marks) an exported symbol. 806 * 807 * @returns see symAdd() 808 * @param pWld Pointer to linker instance. 809 * @param pMod Pointer to module 810 * @param fLibSearch Set if we're doing library search at this time. 811 * @param fExport Export flags (WLDSEF_*). 812 * @param cExpWords Number of words to push on the stack if this 813 * export is a call gate. 814 * @param pachExpName Exported name. 815 * @param cchExpName Length of that name. -1 if zero terminated string. 816 * @param pachIntName Internal name. NULL or with cchIntName == 0 if the same 817 * as the exported one. 818 * @param cchIntName Length of that name. -1 if zero terminated string. 819 * 0 if the internal name is the same and the exported one. 820 * @param uOrdinal The ordinal it's exported with 821 * 0 if exported by the name pachIntName represent. 822 */ 823 static PWLDSYM symAddExport(PWLD pWld, PWLDMOD pMod, int fLibSearch, 824 unsigned fExport, 825 unsigned cExpWords, 826 const char *pachExpName, int cchExpName, 827 const char *pachIntName, int cchIntName, 828 unsigned uOrdinal) 829 { 830 PWLDSYM pSym; 831 832 /* set default name */ 833 if (!pachIntName || !cchIntName) 834 { 835 pachExpName = pachIntName; 836 cchExpName = cchIntName; 837 } 838 839 /* 840 * Add external name. 841 */ 842 pSym = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0), 843 pachExpName, cchExpName, 0, 0, NULL); 844 if (!pSym) 845 return NULL; 846 847 /* 848 * Is the exported symbol already exported? 849 */ 850 if (pSym->fFlags & WLDSF_EXPORT) 851 { 852 /* Just warn and ignore */ 853 modWarn(pMod, "Export '%s' is already defined.", pSym->pszName); 854 } 855 else 856 { 857 PWLDSYM pSymAlias; 858 859 /* 860 * Add internal name. 861 */ 862 pSymAlias = symAdd(pWld, pMod, WLDSF_UNDEF | (fLibSearch ? WLDSF_LIBSEARCH : 0), 863 pachIntName, cchIntName, 0, 0, NULL); 864 if (!pSymAlias) 865 return NULL; 866 if (pSymAlias != pSym && (pSym->fFlags & WLDSF_ALIAS) && pSym->pAliasFor != pSymAlias) 867 { 868 modError(pMod, "Can't export an alias!."); 869 pSym = NULL; 870 } 871 else 872 { 873 if (pSym->pAliasFor != pSymAlias) 874 { 875 pSym->fFlags |= WLDSF_ALIAS; 876 pSym->pAliasFor = pSymAlias; 877 } 878 pSym->fExport = fExport; 879 pSym->cExpWords = cExpWords; 880 pSym->uExpOrd = uOrdinal; 881 } 882 } 883 884 return pSym; 885 } 886 411 887 /** 412 888 * Reads an OMF module from a file. 413 889 * 414 * This may be part of a library file so, we'll only read from THEADR to 890 * This may be part of a library file so, we'll only read from THEADR to 415 891 * past the first MODEND or the Pass 1 comment record. 416 * The function will return the module stream positioned after the last 892 * The function will return the module stream positioned after the last 417 893 * record it read. 418 894 * 419 895 * @returns 0 on success. 420 896 * @returns non zero on failure. 421 * @param pWld Pointer to linker instance. 422 * @param pMod Pointer to module 423 */ 424 static unsigned pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod) 425 { 897 * @param pWld Pointer to linker instance. 898 * @param pMod Pointer to module 899 * @param fLibSearch Set if we're doing library search at this time. 900 */ 901 static unsigned pass1ReadOMFMod(PWLD pWld, PWLDMOD pMod, int fLibSearch) 902 { 903 OMFREC OmfRec = {0,0}; 426 904 FILE * phFile; /* Input file. */ 427 PWLDSYM papExts[] = NULL;/* Pointer to an array of EXTDEFs (as they appear) */905 PWLDSYM * papExts = NULL; /* Pointer to an array of EXTDEFs (as they appear) */ 428 906 /* We need them for the WKEXT processing. */ 429 907 int cExts = 0; /* Number of Entries in papExts. */ 430 908 int fFirst = 1; /* First record indicator. */ 431 909 /* generic stuff we'll use alot with not status associated. */ 432 int cch; 910 int cch; 433 911 PWLDSYM pSym; 434 912 PWLDSYM pSym2; 913 int i; 914 unsigned long ul; 915 unsigned short us; 916 unsigned char uch, uch2, uch3; 435 917 436 918 … … 442 924 for (;;) 443 925 { 444 OMFREC OmfRec;445 926 unsigned char achBuffer[OMF_MAX_REC + 8]; 446 union 927 union 447 928 { 448 929 unsigned char * puch; … … 452 933 unsigned long * pul; 453 934 signed long * pl; 935 void * pv; 454 936 } u, u1, u2, u3; 455 937 /** macro for getting a OMF index out of the buffer */ … … 476 958 } 477 959 } 478 960 479 961 /* Read or skip the record. */ 480 962 switch (OmfRec.chType) … … 482 964 /* done */ 483 965 case MODEND: case MODEND | REC32: 484 case LIBEND: 966 case LIBEND: 485 967 fseek(phFile, OmfRec.cb, SEEK_CUR); 486 968 goto done_skip; 487 969 /* read */ 488 case EXTDEF: case EXTDEF | REC32: 489 case PUBDEF: case PUBDEF | REC32: 970 case EXTDEF: case EXTDEF | REC32: 971 case PUBDEF: case PUBDEF | REC32: 490 972 case ALIAS: case ALIAS | REC32: 491 case COMDEF: case COMDEF | REC32: 492 case COMDAT: case COMDAT | REC32: 493 case COMENT: case COMENT | REC32: 494 case LIBHDR: 973 case COMDEF: case COMDEF | REC32: 974 case COMDAT: case COMDAT | REC32: 975 case COMENT: case COMENT | REC32: 976 case LIBHDR: 495 977 break; 496 978 /* skip */ … … 502 984 { 503 985 modError(pMod, "read error. (offset ~= %#x)", ftell(phFile)); 504 goto failure; 986 goto failure; 505 987 } 506 988 … … 508 990 switch (OmfRec.chType) 509 991 { 510 case COMENT: case COMENT | REC32: 992 case COMENT: case COMENT | REC32: 511 993 switch (*++u.pch) 512 994 { … … 514 996 goto done_noskip; 515 997 case CLASS_WKEXT: 516 { /* This is a bit tricky, we need to have an indexable array 517 * of the extdefs for this module. In addition we'll need to 998 { /* This is a bit tricky, we need to have an indexable array 999 * of the extdefs for this module. In addition we'll need to 518 1000 * make sure we don't mark an EXTDEF from another module as 519 * weak. 1001 * weak. 520 1002 */ 521 1003 while (OMF_MORE()) … … 523 1005 int iWeak = OMF_GETINDEX(); 524 1006 int iDefault = OMF_GETINDEX(); 525 if ( iWeak >= cExts 1007 if ( iWeak >= cExts 526 1008 || iDefault >= cExts 527 1009 || !papExts[iWeak] 528 1010 || !papExts[iDefault]) 1011 { 529 1012 modError(pMod, "Invalid WKEXT record."); 530 if (papExts[iWeak]->eFlags & WLDSF_UNCERTAIN) 1013 goto failure; 1014 } 1015 if ((papExts[iWeak]->fFlags & (WLDSF_TYPEMASK | WLDSF_UNCERTAIN)) == (WLDSF_UNDEF | WLDSF_UNCERTAIN)) 531 1016 { 532 papExts[iWeak]-> eFlags = (papExts[iWeak]->eFlags & ~WLDSF_STATEMASK) | WLDSF_WKEXT;1017 papExts[iWeak]->fFlags = (papExts[iWeak]->fFlags & ~(WLDSF_TYPEMASK | WLDSF_UNCERTAIN)) | WLDSF_WKEXT; 533 1018 papExts[iWeak]->pWeakDefault = papExts[iDefault]; 534 1019 } 535 else if ( (papExts[iWeak]-> eFlags & WLDSF_STATEMASK) == WLDSF_WKEXT1020 else if ( (papExts[iWeak]->fFlags & WLDSF_TYPEMASK) == WLDSF_WKEXT 536 1021 && papExts[iWeak]->pWeakDefault != papExts[iDefault]) 537 modWarn(pMod, "WKEXT '%s' al lready declared with '%s' and not '%s' as default.",1022 modWarn(pMod, "WKEXT '%s' already declared with '%s' and not '%s' as default.", 538 1023 papExts[iWeak]->pszName, papExts[iWeak]->pWeakDefault->pszName, papExts[iDefault]->pszName); 539 1024 } 540 1025 break; 541 1026 } 542 1027 543 1028 case CLASS_OMFEXT: 544 1029 { … … 549 1034 case OMFEXT_IMPDEF: 550 1035 { 551 int fOrd = OMF_BYTE(); 552 cch = OMF_BYTE(); 553 pSym = symNew(pWld, WLDSF_STRONG | WLDSF_IMPORT, u.pch, cch); 1036 uch = OMF_BYTE(); /* flags */ 1037 u1 = u; u.pch += 1 + *u.puch; /* internal name */ 1038 u2 = u; u.pch += 1 + *u.puch; /* module name */ 1039 ul = 0; /* ordinal */ 1040 if (uch & 1) 1041 ul = OMF_WORD(); 1042 1043 pSym = symAddImport(pWld, pMod, fLibSearch, 1044 u1.pch + 1, *u1.puch, 1045 u2.pch + 1, *u2.puch, 1046 ul); 554 1047 if (!pSym) goto failure; 555 u.pch += cch;556 cch = OMF_BYTE();557 pSym->pszImpMod = strpool_addn(pWld->pStrMisc, u.pch, cch);558 u.pch += cch;559 if (fOrd)560 pSym->iImpOrd = OMF_WORD();561 1048 break; 562 1049 } 563 1050 564 /* 1051 /* 565 1052 * Export definition. 566 1053 * If it have an internal name the exported name will become … … 569 1056 case OMFEXT_EXPDEF: 570 1057 { 571 u1 = u; u.pch++; 572 u2 = u; u.pch+ = 1 + *u2.pch; 573 u3 = u; u.pch+ = 1 + *u3.pch; 574 575 pSym2 = NULL; 576 if (*u3.pch) 577 { 578 pSym2 = symNew(pWld, WLDSF_UNDEF, u3.pch + 1, *u3.pch); 579 if (!pSym2) goto failure; 580 pSym = symNew(pWld, WLDSF_STRONG | WLDSF_ALIAS | WLDSF_EXPORT, u2.pch + 1, *u2.pch); 581 if (!pSym) goto failure; 582 pSym->pAliasFor = pSym2; 583 } 584 else 585 { 586 pSym = symNew(pWld, WLDSF_UNDEF | WLDSF_EXPORT, u2.pch + 1, *u2.pch); 587 if (!pSym) goto failure; 588 } 1058 u1 = u; u.pch++; /* flags */ 1059 u2 = u; u.pch += 1 + *u.puch; /* exported name */ 1060 u3 = u; u.pch += 1 + *u.puch; /* internal name */ 1061 ul = 0; /* ordinal */ 589 1062 if (*u1.pch & 0x80) 590 pSym->iExpOrd = GET_BYTE(); 591 if (*u1.pch & 0x40) 592 pSym->fExport.fResidentName = 1; 593 594 1063 pSym->uExpOrd = OMF_BYTE(); 1064 pSym = symAddExport(pWld, pMod, fLibSearch, 1065 (*u1.puch & 0x40 ? WLDSEF_RESIDENT : WLDSEF_DEFAULT) | (*u1.puch & 0x20 ? WLDSEF_NODATA : 0), 1066 ((unsigned)*u1.puch) & 0x1f, 1067 u2.pch + 1, *u1.puch, 1068 u3.pch + 1, *u2.puch, 1069 ul); 1070 if (!pSym) goto failure; 595 1071 break; 596 1072 } 597 1073 } 598 599 1074 } 600 601 } 1075 } /* comment class */ 602 1076 break; 603 1077 604 1078 case EXTDEF: case EXTDEF | REC32: 605 1079 { 606 607 1080 break; 608 1081 } 609 1082 610 case PUBDEF: case PUBDEF | REC32: 1083 case PUBDEF: case PUBDEF | REC32: 611 1084 { 612 1085 break; … … 618 1091 } 619 1092 620 case COMDEF: case COMDEF | REC32: 1093 case COMDEF: case COMDEF | REC32: 621 1094 { 622 1095 break; 623 1096 } 624 1097 625 case COMDAT: case COMDAT | REC32: 1098 case COMDAT: case COMDAT | REC32: 626 1099 { 627 1100 break; … … 647 1120 /* Make all the EXTDEFs uncertain. */ 648 1121 for (i = 0; i < cExts; i++) 649 papExts[i]-> eFlags &= ~WLDSF_UNCERTAIN;1122 papExts[i]->fFlags &= ~WLDSF_UNCERTAIN; 650 1123 651 1124 return 0; … … 661 1134 662 1135 /******************************************************************************* 663 * 1136 * 664 1137 * P u b l i c I n t e r f a c e 665 1138 * P u b l i c I n t e r f a c e 666 1139 * P u b l i c I n t e r f a c e 667 * 1140 * 668 1141 *******************************************************************************/ 669 1142 … … 680 1153 { 681 1154 PWLD pWld = xmalloc(sizeof(*pWld)); 682 1155 683 1156 /* initiate it */ 684 1157 memset(pWld, 0, sizeof(*pWld)); … … 723 1196 * @returns some unexplainable randomly picked number on failure. 724 1197 * @param pWld Linker instance to destroy. 725 * @param phFile File handle to pszName. 1198 * @param phFile File handle to pszName. 726 1199 * @param pszName Object file to add. This may be an OMF library too, 727 1200 * but that only means that all it's content is to be 728 * linked in as if they have been all specified on the 1201 * linked in as if they have been all specified on the 729 1202 * commandline. 730 * @remark Don't call wld_add_object after wld_add_library() 1203 * @remark Don't call wld_add_object after wld_add_library() 731 1204 * or wld_generate_weaklib()! 732 1205 */ … … 759 1232 *pWld->ppObjsAdd = pMod; 760 1233 pWld->ppObjsAdd = &pMod->pNext; 761 rc = pass1ReadOMFMod(pWld, pMod );1234 rc = pass1ReadOMFMod(pWld, pMod, 0); 762 1235 } 763 1236 else if (OmfRec.chType == LIBHDR) … … 783 1256 fprintf(stderr, "weakld: info: adding library member '%s'.\n", achModName); 784 1257 } 785 rc = pass1ReadOMFMod(pWld, pMod );1258 rc = pass1ReadOMFMod(pWld, pMod, 0); 786 1259 if (rc) 787 1260 break; … … 817 1290 * The handle may be closed on exit, or latest when 818 1291 * we destroy the linker. 819 * @param pszName Definition file to add. 820 * @remark Don't call wld_add_deffile after wld_add_library() 1292 * @param pszName Definition file to add. 1293 * @remark Don't call wld_add_deffile after wld_add_library() 821 1294 * or wld_generate_weaklib()! 822 1295 */ … … 868 1341 869 1342 /** 870 * Generates a object file containing alias for resolving the weak 1343 * Generates a object file containing alias for resolving the weak 871 1344 * symbol references in the linked executable. 872 1345 * The filename of the object will be generated, but of course it -
Property cvs2svn:cvs-rev
changed from
-
trunk/src/emx/src/emxomf/weakld.h
-
Property cvs2svn:cvs-rev
changed from
1.1
to1.2
r490 r491 31 31 struct wld; 32 32 typedef struct wld * PWLD; 33 33 34 34 /** wld_create() flags. */ 35 35 enum wld_create_flags 36 36 { 37 37 /** Verbose */ 38 WLDC_VERBOSE = 1, 38 WLDC_VERBOSE = 1, 39 39 /** Skip extended dictionary of libraries. */ 40 WLDC_NO_EXTENDED_DICTIONARY_SEARCH = 2, 40 WLDC_NO_EXTENDED_DICTIONARY_SEARCH = 2, 41 /** Case in-sensitive symbol resolution. */ 42 WLDC_CASE_INSENSITIVE = 4, 41 43 }; 42 44 … … 52 54 int wld_destroy(PWLD pWld); 53 55 54 #endif 56 #endif -
Property cvs2svn:cvs-rev
changed from
Note:
See TracChangeset
for help on using the changeset viewer.