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

📄 fixup.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 2 页
字号:
     For j=0; j<block_count; j++
      BeginFor
       fixup_LIDATA_IDB();
      EndFor;
    EndFor;
  Else  /* Handle non-recursive case:  Content is data. */
   len = Bit_16(*obj_ptr.b8++);
   For i=0; i<repeat_count; i++
    BeginFor
     far_move(lseg_data_ptr, obj_ptr.b8, len);
     lseg_data_ptr += len;
    EndFor;
   obj_ptr.b8 += len;
  EndIf;
 return;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           fixup_LIDATA_record                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void fixup_LIDATA_record()
BeginDeclarations
lseg_ptr                               lseg;
#define Lseg                           (*lseg)
EndDeclarations
BeginCode
 lseg          = (*fixup_temp).lseg;
 lseg_data_ptr = Addr(Lseg.data[(*fixup_temp).offset]);
 far_move(BytePtr(object_file_element),(*fixup_temp).data, (*fixup_temp).rec_len) ;
 obj_ptr.b8       = object_file_element;
 end_of_record.b8 = Addr(obj_ptr.b8[(*fixup_temp).rec_len]);
 While obj_ptr.b8 IsNot end_of_record.b8
  BeginWhile
   fixup_LIDATA_IDB();
  EndWhile;
 return;
EndCode
#undef Lseg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                                 frame                                   |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 frame()
BeginDeclarations
bit_32                                 frame_address;
group_entry_ptr                        grp;
#define Grp                            (*grp)
lseg_ptr                               lseg;
#define Lseg                           (*lseg)
public_entry_ptr                       pub;
#define Pub                            (*pub)
segment_entry_ptr                      seg;
#define Seg                            (*seg)
EndDeclarations
BeginCode
 Using fixup.frame_method
  BeginCase
   When 0:  /* Frame is segment relative */
    lseg           = (lseg_ptr) fixup.frame_referent;
    frame_absolute = Lseg.align Is absolute_segment;
    seg            = Lseg.segment;
    frame_address  = Seg.address;
    break;
   When 1:  /* Frame is group relative */
    grp            = (group_entry_ptr) fixup.frame_referent;
    seg            = Grp.first_segment;
    If seg IsNull
     Then
      frame_absolute = False; /* hack for FLAT groups (no segs) */
      frame_address = FLAT_address;
     Else
      lseg           = Seg.lsegs.first;
      frame_absolute = Lseg.align Is absolute_segment;
      frame_address  = Seg.address;
     EndIf;
    break;
   When 2:  /* Frame is relative to external */
    pub = (public_entry_ptr) fixup.frame_referent;
    frame_address = public_frame_address(pub);
    break;
   When 3:  /* Frame is absolute */
    frame_absolute = True;
    frame_address  = Bit_32(fixup.frame_referent);
    break;
   When 4:  /* Frame is segment containing location */
    lseg           = (*fixup_temp).lseg;
    seg            = Lseg.segment;
    frame_absolute = Lseg.align Is absolute_segment;
    frame_address  = Seg.address;
    break;
   When 5:  /* Frame is defined by target */
    Using fixup.target_method
     BeginCase
      When 0:  /* Target is segment relative */
       lseg           = (lseg_ptr) fixup.target_referent;
       seg            = Lseg.segment;
       frame_absolute = Lseg.align Is absolute_segment;
       frame_address  = Seg.address;
       break;
      When 1:  /* Target is group relative */
       grp = (group_entry_ptr) fixup.target_referent;
       seg            = Grp.first_segment;
       lseg           = Seg.lsegs.first;
       frame_absolute = Lseg.align Is absolute_segment;
       frame_address  = Seg.address;
       break;
      When 2:  /* Target is relative to an external */
       pub = (public_entry_ptr) fixup.target_referent;
       frame_address = public_frame_address(pub);
       break;
      When 3:  /* Target is absolute */
       frame_absolute = True;
       frame_address  = Bit_32(fixup.target_referent);
       break;
     EndCase;
    break;
   When 6:  /* No frame */
    frame_absolute = False;
    frame_address = 0L;
    break;
  EndCase;
 return(frame_address & 0xFFFFFFF0L);
EndCode
#undef Grp
#undef Lseg
#undef Pub
#undef Seg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                               pass_two                                  |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void pass_two()
BeginDeclarations
group_entry_ptr                        dgroup_entry;
segment_entry_ptr                      seg;
#define Group                          (*dgroup_entry)
#define Seg                            (*seg)
EndDeclarations
BeginCode
 fixup_start_time = Now;

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |      First, we will figure out how long the EXE header will be.         |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
 If exefile IsTrue
  Then
   exe_header_size  = Bit_32(sizeof(EXE_header_type)) - 
                      Bit_32(sizeof(bit_32)) + 
                     (Bit_32(sizeof(bit_32)) * Bit_32(n_relocation_items));
   If align_exe_header.val IsTrue
    Then
     exe_header_size += AlignmentGap(exe_header_size, 0xFL);
    Else
     exe_header_size += AlignmentGap(exe_header_size, 0x1FFL);
    EndIf;
   exe_header       = (EXE_header_ptr)
                       allocate_memory(exe_header_size);
   far_set(BytePtr(exe_header), 0, Bit_16(exe_header_size));
  EndIf;
 fixup_temp = fixup_list ;
 While fixup_temp IsNotNull
  BeginWhile
   Using (*fixup_temp).rec_typ And Complement 1
    BeginCase
     When FIXUPP_record:
      fixup_FIXUPP_record();
      break;
     When FORREF_record:
      fixup_FORREF_record();
      break;
     When LEDATA_record:
      fixup_LEDATA_record();
      break;
     When LIDATA_record:
      fixup_LIDATA_record();
      break;
     Otherwise:
      linker_error(16, "Internal logic error:  Invalid temp file record.\n");
      break;
    EndCase;
   fixup_temp = (*fixup_temp).next ;
  EndWhile;
 return;
EndCode
#undef Group
#undef Seg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                          public_frame_address                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 public_frame_address(public_entry_ptr pub)
BeginDeclarations
bit_32                                 address;
#define Pub                            (*pub)
segment_entry_ptr                      seg;
#define Seg                            (*seg)
EndDeclarations
BeginCode
 frame_absolute = False;
 If Pub.type_entry IsNot internal
  Then
   seg = (*(*fixup_temp).lseg).segment;
   If Not fixup.external_error_detected And Not Pub.did_external_error
    Then
     linker_error(-1, "Unresolved External \"%s\" in Module \"%s\"\n",
                     unmangle(Pub.symbol),
                     (*(*(*fixup_temp).lseg).tmodule).symbol);
     fixup.external_error_detected = True;
     Pub.did_external_error = True ;
    EndIf;
   address = 0L;
  Else
	 If Pub.type_qualifier IsEqualTo public_import
		Then
			return 0;
		EndIf ;
   If Pub.Internal.group IsNull
    Then
     If Pub.Internal.lseg IsNull
      Then
       frame_absolute = True;
       address        = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
      Else
       frame_absolute = (*Pub.Internal.lseg).align Is absolute_segment;
       address        = (*(*Pub.Internal.lseg).segment).address;
      EndIf;
    Else
     If (*Pub.Internal.group).first_segment IsZero
      Then
        /* hack for flat groups */
        address = FLAT_address ;
#ifdef XXXXX
       If Pub.Internal.lseg IsNull
        Then
         address        = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
        Else
         address        = (*(*Pub.Internal.lseg).segment).address;
        EndIf;
#endif
      Else
       frame_absolute = 
               (*(*(*Pub.Internal.group).first_segment).lsegs.first).align Is
               absolute_segment;
       address        = (*(*Pub.Internal.group).first_segment).address;
      EndIf;
    EndIf;
  EndIf;
 return(address);
EndCode
#undef Pub
#undef Seg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                         public_target_address                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 public_target_address(public_entry_ptr pub)
BeginDeclarations
bit_32                                 address;
#define Pub                            (*pub)
segment_entry_ptr                      seg;
#define Seg                            (*seg)
EndDeclarations
BeginCode
 If Pub.type_entry IsNot internal
  Then
   seg = (*(*fixup_temp).lseg).segment;
   If Not fixup.external_error_detected And Not Pub.did_external_error
    Then
     linker_error(-1, "Unresolved External \"%s\" in Module \"%s\"\n",
                     unmangle(Pub.symbol),
                     (*(*(*fixup_temp).lseg).tmodule).symbol);
     Pub.did_external_error = True ;
     fixup.external_error_detected = True;
    EndIf;
   address = 0L;
  Else
	 If Pub.type_qualifier IsEqualTo public_import
		Then
			return 0;
		EndIf ;
   If Pub.Internal.lseg IsNull
    Then
     address = (Bit_32(Pub.Internal.frame) ShiftedLeft 4);
    Else
     address = (*Pub.Internal.lseg).address;
    EndIf;
  EndIf;
 return(address + Bit_32(Pub.Internal.offset));
EndCode
#undef Pub
#undef Seg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                              segment_offset                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 segment_offset(lseg_ptr lseg, bit_32 offset)
BeginDeclarations
#define Lseg                           (*lseg)
bit_32                                 totaloffs;
EndDeclarations
BeginCode
 totaloffs = Bit_32(offset) + Target(lseg);
 totaloffs = ((totaloffs And 0xffff0000) ShiftedLeft 12) Or 
                  (totaloffs And 0xffff);
 return ((Frame(lseg) ShiftedLeft 12L) Or totaloffs);
EndCode
#undef Lseg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                                 target                                   |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
bit_32 target(public_entry_ptr *import)
BeginDeclarations
group_entry_ptr                        grp;
#define Grp                            (*grp)
lseg_ptr                               lseg;
#define Lseg                           (*lseg)
public_entry_ptr                       pub;
#define Pub                            (*pub)
bit_32                                 target_address;
EndDeclarations
BeginCode
 (*import) = NULL ;
 Using fixup.target_method
  BeginCase
   When 0:  /* Target is segment relative */
    lseg = (lseg_ptr) fixup.target_referent;
    target_address = Lseg.address + Bit_32(fixup.target_offset);
    break;
   When 1:  /* Target is group relative */
    grp = (group_entry_ptr) fixup.target_referent;
    target_address = (*Grp.first_segment).address +
                      Bit_32(fixup.target_offset);
    break;
   When 2:  /* Target is relative to an external */
    pub = (public_entry_ptr) fixup.target_referent;
    Pub.use_count++;
    If Pub.type_qualifier IsEqualTo public_import
      Then
        (*import) = pub ;
      EndIf ;
    target_address = public_target_address(pub) +
                      Bit_32(fixup.target_offset);
    break;
   When 3:  /* Target is absolute */
    target_address = Bit_32(fixup.target_referent) +
                      Bit_32(fixup.target_offset);
    break;
  EndCase;
 return(target_address);
EndCode
#undef Grp
#undef Lseg
#undef Pub


⌨️ 快捷键说明

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