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