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