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

📄 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 页
字号:
bit_16 obj_FIXUPP()
BeginDeclarations
EndDeclarations
BeginCode
 If Current_record_header.rec_typ IsNot FIXUPP_record
  Then
   return(False);
  EndIf;
 FIXUPP_contains_only_threads = True;
 While obj_ptr.b8 IsNot end_of_record.b8
  BeginWhile
   If (*obj_ptr.TRD_DAT).type_fixupp_record IsZero
    Then
     obj_FIXUPP_thread();
    Else
     FIXUPP_contains_only_threads = False;
     obj_FIXUPP_fixup();
    EndIf;
  EndWhile;
 obj_next_record();
 return(True);
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           obj_FIXUPP_fixup                              |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void obj_FIXUPP_fixup()
BeginDeclarations
FIX_DAT_type                           FIX_DAT;
bit_16                                 frame_method;
LOCAT_type                             LOCAT;
bit_16                                 target_method;
bit_8                                  temp;
bit_16                                 thread_number;
EndDeclarations
BeginCode
/*+-------------------------------------------------------------------------+
  |                                                                         |
  | The LOCAT field in a FIXUPP record has its low and high bytes swapped   |
  | because the high order bit must be 0 for threads and 1 for fixups.      |
  | Since that bit could not be placed in the offset, the bytes were        |
  | swapped instead.                                                        |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 temp                  = obj_ptr.b8[0];
 obj_ptr.b8[0]         = obj_ptr.b8[1];
 obj_ptr.b8[1]         = temp;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |          Pick up the two required fields (LOCAT and FIX_DAT)            |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 LOCAT                 = *obj_ptr.LOCAT++;
 FIX_DAT               = *obj_ptr.FIX_DAT++;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |          A fixup consists of a location, mode, frame and target.        |
  |                         Process the location part.                      |
  |                                                                         |
  +-------------------------------------------------------------------------+*/

 fixup_index           = LOCAT.data_record_offset;
 fixup.location_type   = LOCAT.loc;

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

 fixup.mode            = LOCAT.m;

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

 If FIX_DAT.f IsZero
  Then  /* Frame is specified explicitly */
   frame_method         = FIX_DAT.frame;
   fixup.frame_method   = frame_method;
   Using frame_method
    BeginCase
     When 0:
      fixup.frame_referent = (void     *) snames[obj_index_segment()];
      break;
     When 1:
      fixup.frame_referent = (void     *) gnames[obj_index_group()];
      break;
     When 2:
      fixup.frame_referent = (void     *) externals[obj_index_external()];
      break;
     When 3:
      fixup.frame_referent =
       (void     *) (Bit_32(*obj_ptr.b16++) ShiftedLeft 4);
     Otherwise:
      fixup.frame_referent = Null;
      break;
    EndCase;
  Else  /* Frame is specified by a thread */
   thread_number        = FIX_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;
   fixup.frame_referent = frame_thread[thread_number].referent;
   fixup.frame_method   = frame_thread[thread_number].method;
  EndIf;

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

 If FIX_DAT.t IsZero
  Then  /* Target is specified explicitly */
   target_method       = FIX_DAT.targt;
   fixup.target_method = target_method;
   Using target_method
    BeginCase
     When 0:  /* Target is the segment referenced by the index */
      fixup.target_referent = (void     *) snames[obj_index_segment()];
      break;
     When 1:  /* Target is the lowest seg in the group referenced 
                 by the index */
      fixup.target_referent = (void     *) gnames[obj_index_group()];
      break;
     When 2:
      fixup.target_referent = (void     *) externals[obj_index_external()];
      break;
     When 3:
      fixup.target_referent =
       (void     *) (Bit_32(*obj_ptr.b16++) ShiftedLeft 4);
      break;
    EndCase;
  Else  /* Target is specified by a thread */
   thread_number         = FIX_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;
   fixup.target_referent = target_thread[thread_number].referent;
   fixup.target_method   = target_thread[thread_number].method;
  EndIf;

 If FIX_DAT.p IsZero
  Then  /* There is a target displacement */
   fixup.target_offset = *obj_ptr.b16++;
  Else  /* The target displacement is zero */
   fixup.target_offset = 0;
  EndIf;

 fixup.external_error_detected = False;

 If (fixup.mode IsZero) AndIf
                             ((fixup.location_type Is base_location)    OrIf
                              (fixup.location_type Is pointer_location) OrIf
                              (fixup.location_type Is hibyte_location))
  Then /* Undefined fixup action */
   linker_error(4, "Possible translator error:\n"
                   "\tModule:  \"%Fs\"\n"
                   "\t  File:  \"%Fs\"\n"
                   "\tOffset:  %lu\n"
                   "\t Error:  Base, pointer or hibyte self-relative fixups\n"
                   "\t         are undefined.\n",
                   (*tmodule_name).symbol,
                   (*infile.file_info).filename,
                   current_record_offset);
  EndIf;

 If last_LxDATA_record_type Is LEDATA_record
  Then
   If ((fixup.location_type Is base_location)     OrIf
       (fixup.location_type Is pointer_location)) AndIf
      (exefile IsTrue)
    Then /* Base and pointer locations will require a relocation item
            in the EXE header */
     n_relocation_items++;
    EndIf;
   write_temp_file(Current_record_header.rec_typ,
                   last_LxDATA_lseg,
                   last_LxDATA_offset + fixup_index,
                   BytePtr(Addr(fixup)),
                   sizeof(fixup));
  Else
   If fixup.mode IsZero
    Then
     linker_error(4, "Translator warning:\n"
                     "\tModule:  \"%Fs\"\n"
                     "\t  File:  \"%Fs\"\n"
                     "\tOffset:  %lu\n"
                     "\t Error:  Self-relative fixup not permitted for "
                                 "LIDATA.\n",
                     (*tmodule_name).symbol,
                     (*infile.file_info).filename,
                     current_record_offset);
    Else
     obj_fixup_LIDATA();
    EndIf;
  EndIf;

 return;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            obj_fixup_LIDATA                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void obj_fixup_LIDATA()
BeginDeclarations
obj_ptr_type                           old_obj_ptr;
EndDeclarations
BeginCode
 LIDATA_index  = 0;
 LIDATA_offset = last_LxDATA_offset;
 old_obj_ptr   = obj_ptr;
 obj_ptr.b8    = Last_LIDATA_record_header.variant_part;
 end_of_last_LIDATA_record.b8 =
  (byte *)
   Addr(Last_LIDATA_record_header.variant_part
    [Last_LIDATA_record_header.rec_len-1]);
 obj_index_segment();
 obj_ptr.b16++;
 While obj_ptr.b8 IsNot end_of_last_LIDATA_record.b8
  BeginWhile
   obj_fixup_LIDATA_IDB();
  EndWhile;
 obj_ptr = old_obj_ptr;
 return;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           obj_fixup_LIDATA_IDB                          |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void obj_fixup_LIDATA_IDB()
BeginDeclarations
bit_16                                 block_count;
bit_8                                 *content;
bit_16                                 i;
bit_16                                 j;
bit_16                                 len;
bit_16                                 old_index;
bit_16                                 repeat_count;
EndDeclarations
BeginCode
 repeat_count = *obj_ptr.b16++;  LIDATA_index += sizeof(bit_16);
 block_count  = *obj_ptr.b16++;  LIDATA_index += sizeof(bit_16);
 content      = obj_ptr.b8;
 old_index    = LIDATA_index;
 If block_count IsNotZero
  Then  /* Handle recursive case:  Content is iterated data block */
   For i=0; i<repeat_count; i++
    BeginFor
     obj_ptr.b8 = content;
     LIDATA_index = old_index;
     For j=0; j<block_count; j++
      BeginFor
       obj_fixup_LIDATA_IDB();
      EndFor;
    EndFor;
  Else  /* Handle non-recursive case:  Content is data. */
   For i=0; i<repeat_count; i++
    BeginFor
     obj_ptr.b8   = content;
     LIDATA_index = old_index;
     len          = Bit_16(*obj_ptr.b8++);  LIDATA_index += sizeof(bit_8);
     If (fixup_index NotLessThan LIDATA_index)        AndIf
        (fixup_index LessThan   (LIDATA_index + len))
      Then
       write_temp_file(Current_record_header.rec_typ,
                       last_LxDATA_lseg,
                       LIDATA_offset + fixup_index - LIDATA_index,
                       BytePtr(Addr(fixup)),
                       sizeof(fixup));
       If ((fixup.location_type Is base_location)     OrIf
           (fixup.location_type Is pointer_location)) AndIf
          (exefile IsTrue)
        Then /* Base and pointer locations will require a relocation item
                in the EXE header */
         n_relocation_items++;
        EndIf;
      EndIf;
     LIDATA_offset += len;
    EndFor;
   obj_ptr.b8    += len;
   LIDATA_index  += len;
  EndIf;
 return;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           obj_FIXUPP_thread                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void obj_FIXUPP_thread()
BeginDeclarations
bit_16                                 method;
bit_16                                 thread;
TRD_DAT_type                           TRD_DAT;
EndDeclarations
BeginCode
 TRD_DAT = *obj_ptr.TRD_DAT++;
 thread  = TRD_DAT.thred;
 method  = TRD_DAT.method;
 If TRD_DAT.d IsZero
  Then  /* This is a target thread */
   target_thread[thread].method = Bit_8(method);
   target_thread[thread].thread_defined = True;
   Using method
    BeginCase
     When 0:
      target_thread[thread].referent =
       (void     *) snames[obj_index_segment()];
      break;
     When 1:
      target_thread[thread].referent =
       (void     *) gnames[obj_index_group()];
      break;
     When 2:

⌨️ 快捷键说明

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