📄 fixup.c
字号:
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 + -