⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmodule.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
 If Current_record_header.rec_typ IsNot MODEND_record
  Then
   return(False);
  EndIf;
 MOD_TYP = *obj_ptr.MOD_TYP++;

 If MOD_TYP.zeros IsNotZero
  Then
   linker_error(4, "Translator error:\n"
                   "\tModule:  \"%Fs\"\n"
                   "\t  File:  \"%Fs\"\n"
                   "\tOffset:  %lu\n"
                   "\t Error:  Bits 1 thru 5 of MOD TYP must be zero.\n",
                   (*tmodule_name).symbol,
                   (*infile.file_info).filename,
                   current_record_offset);
  EndIf;

 If (MOD_TYP.mattr IsNot 1) AndIf (MOD_TYP.mattr IsNot 3)
  Then  /* We have no starting address */
   return(True);
  EndIf;

 If MOD_TYP.l IsNot 1
  Then
   linker_error(4, "Translator error:\n"
                   "\tModule:  \"%Fs\"\n"
                   "\t  File:  \"%Fs\"\n"
                   "\tOffset:  %lu\n"
                   "\t Error:  Bit 0 of MOD TYP must be one.\n",
                   (*tmodule_name).symbol,
                   (*infile.file_info).filename,
                   current_record_offset);
  EndIf;

 If start_address_found IsTrue
  Then
   linker_error(4, "Multiple start address encountered.  The start address\n"
                   "in module \"%Fs\" of file \"%Fs\" has been ignored.\n",
                   (*tmodule_name).symbol,
                   (*infile.file_info).filename);
  EndIf;

 start_address_found = True;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                  Pick up the required field END_DAT.                    |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 END_DAT = *obj_ptr.FIX_DAT++;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                         Process the frame part.                         |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 If END_DAT.f IsZero
  Then  /* Frame is specified explicitly */
   frame_method                 = END_DAT.frame;
   start_address.frame_method   = frame_method;
   Using frame_method
    BeginCase
     When 0:
      start_address.frame_referent =
       (void     *) snames[obj_index_segment()];
      break;
     When 1:
      start_address.frame_referent =
       (void     *) gnames[obj_index_group()];
      break;
     When 2:
      start_address.frame_referent =
       (void     *) externals[obj_index_external()];
      break;
     When 3:
      start_address.frame_referent =
       (void     *) (Bit_32(*obj_ptr.b16++) ShiftedLeft 4);
     Otherwise:
      start_address.frame_referent = Null;
      break;
    EndCase;
  Else  /* Frame is specified by a thread */
   thread_number                = END_DAT.frame;
   If Not frame_thread[thread_number].thread_defined
    Then
     linker_error(12, "Translator error:\n"
                      "\tModule:  \"%Fs\"\n"
                      "\t  File:  \"%Fs\"\n"
                      "\tOffset:  %lu\n"
                      "\t Error:  Reference to frame thread %u which has "
                                  "been defined.n",
                      (*tmodule_name).symbol,
                      (*infile.file_info).filename,
                      current_record_offset,
                      thread_number);
    EndIf;
   start_address.frame_referent = frame_thread[thread_number].referent;
   start_address.frame_method   = frame_thread[thread_number].method;
  EndIf;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                         Process the target part.                        |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 If END_DAT.t IsZero
  Then  /* Target is specified explicitly */
   target_method               = END_DAT.targt;
   start_address.target_method = target_method;
   Using target_method
    BeginCase
     When 0:
      start_address.target_referent =
       (void     *) snames[obj_index_segment()];
      break;
     When 1:
      start_address.target_referent =
       (void     *) gnames[obj_index_group()];
      break;
     When 2:
      start_address.target_referent =
       (void     *) externals[obj_index_external()];
      break;
     When 3:
      start_address.target_referent =
       (void     *) (Bit_32(*obj_ptr.b16++) ShiftedLeft 4);
      break;
    EndCase;
  Else  /* Target is specified by a thread */
   thread_number                 = END_DAT.targt;
   If Not target_thread[thread_number].thread_defined
    Then
     linker_error(12, "Translator error:\n"
                      "\tModule:  \"%Fs\"\n"
                      "\t  File:  \"%Fs\"\n"
                      "\tOffset:  %lu\n"
                      "\t Error:  Reference to target thread %u which has "
                                  "been defined.n",
                      (*tmodule_name).symbol,
                      (*infile.file_info).filename,
                      current_record_offset,
                      thread_number);
    EndIf;
   start_address.target_referent = target_thread[thread_number].referent;
   start_address.target_method   = target_thread[thread_number].method;
  EndIf;

 If END_DAT.p IsZero
  Then  /* There is a target displacement */
   start_address.target_offset = *obj_ptr.b16++;
  Else  /* The target displacement is zero */
   linker_error(12, "Translator error:\n"
                    "\tModule:  \"%Fs\"\n"
                    "\t  File:  \"%Fs\"\n"
                    "\tOffset:  %lu\n"
                    "\t Error:  Only primary fixups allowed in MODEND.\n",
                    (*tmodule_name).symbol,
                    (*infile.file_info).filename,
                    current_record_offset);
   start_address.target_offset = 0;
  EndIf;
 return(True);
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                               obj_MODEXT                                |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_16 obj_MODEXT()
BeginDeclarations
bit_16                                 len;
public_entry_ptr                       pub;
#define Pub                            (*pub)
EndDeclarations
BeginCode
 If Current_record_header.rec_typ IsNot MODEXT_record
  Then
   return(False);
  EndIf;
 While obj_ptr.b8 IsNot end_of_record.b8
  BeginWhile
   If n_externals NotLessThan max_externals.val
    Then
     linker_error(12, "Internal limit exceeded:\n"
                      "\tModule:  \"%Fs\"\n"
                      "\t  File:  \"%Fs\"\n"
                      "\tOffset:  %lu\n"
                      "\t Error:  Too many externals.  Max of %u exceeded.\n"
                      "\t         Retry with larger \"/maxexternals:n\" "
                                  "switch.\n",
                      (*tmodule_name).symbol,
                      (*infile.file_info).filename,
                      current_record_offset,
                      max_externals.val);
    EndIf;
   len         = obj_name_length();
   If case_ignore.val
    Then
     far_to_lower(BytePtr(obj_ptr.b8), len);
    EndIf;
   pub         = lookup_public(len, obj_ptr.b8, tmodule_number);
   obj_ptr.b8 += len;
   obj_name_length();  /* Eat the type index. */
   externals[++n_externals] = pub;
   If Pub.type_entry Is unused
    Then
     Insert pub AtEnd InList external_list EndInsert;
     Pub.type_entry = external;
    EndIf;
  EndWhile;
 obj_next_record();
 return(True);
EndCode
#undef Pub

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                               obj_MODPUB                                |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_16 obj_MODPUB()
BeginDeclarations
bit_16                                 group_index;
bit_16                                 frame;
bit_16                                 len;
public_entry_ptr                       pub;
#define Pub                            (*pub)
bit_16                                 segment_index;
EndDeclarations
BeginCode
 If Current_record_header.rec_typ IsNot MODPUB_record
  Then
   return(False);
  EndIf;
 group_index = obj_index_group();
 segment_index = obj_index_segment();
 If (segment_index IsZero) AndIf (group_index IsZero)
  Then
   frame = *obj_ptr.b16++;
  EndIf;
 While obj_ptr.b8 IsNot end_of_record.b8
  BeginWhile
   len = obj_name_length();
   If case_ignore.val
    Then
     far_to_lower(BytePtr(obj_ptr.b8), len);
    EndIf;
   pub = lookup_public(len, obj_ptr.b8, tmodule_number);
   obj_ptr.b8 += len;
   If Pub.type_entry Is internal
    Then
     linker_error(4, "Duplicate definition of public \"%Fs\".\n"
                     "\tDefinition in module \"%Fs\" of file \"%Fs\" "
                     "ignored.\n",
                     Pub.symbol,
                     (*tmodule_name).symbol,(*infile.file_info).filename);
     obj_ptr.b16++;      /* Eat offset. */
     obj_name_length();  /* Eat type index. */
    Else
     If Pub.type_entry Is unused
      Then
       Insert pub AtEnd InList external_list EndInsert;
      EndIf;
     Pub.type_entry       = internal;
     Pub.Internal.group   = gnames[group_index];
     Pub.Internal.lseg    = snames[segment_index];
     Pub.Internal.frame   = frame;
     Pub.Internal.offset  = *obj_ptr.b16++;
     obj_name_length();  /* Eat type index. */
    EndIf;
  EndWhile;
 obj_next_record();
 return(True);
EndCode
#undef Pub

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              obj_modtail                                |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

/* obj_modtail:: obj_MODEND */

bit_16 obj_modtail()
BeginDeclarations
EndDeclarations
BeginCode
 If obj_MODEND()
  Then
   return(True);
  EndIf;
 return(False);
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                               obj_name                                  |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
lname_entry_ptr obj_name()
BeginDeclarations
lname_entry_ptr                        name;
bit_16                                 len;
EndDeclarations
BeginCode
 len = obj_name_length();
 If len IsZero
  Then
   name = none_lname;
  Else
   If case_ignore.val
    Then
     far_to_lower(BytePtr(obj_ptr.b8), len);
    EndIf;
   name        = lookup_lname(len, obj_ptr.b8);
   obj_ptr.b8 += len;
  EndIf;
 return(name);
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            obj_name_length                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_16 obj_name_length()
BeginDeclarations
EndDeclarations
BeginCode
 If *obj_ptr.b8 LessThan 128
  Then
   return(Bit_16(*obj_ptr.b8++));
  Else
   return((Bit_16(*obj_ptr.b8++ - 128) ShiftedLeft 8) +
          (Bit_16(*obj_ptr.b8++)));
  EndIf;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                             obj_next_record                             |
  |                                                                         |
  +---------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -