📄 tmodule.c
字号:
/*
Copyright 1994-2003 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
You may contact the author at:
mailto::camille@bluegrass.net
or by snail mail at:
David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <string.h>
#include <dos.h>
#include <time.h>
#include "langext.h"
#include "defines.h"
#include "types.h"
#include "subs.h"
#include "globals.h"
/* TMODULE.C */
/*
Object modules are parsed via recursive descent as defined below:
obj_t_module:: obj_THEADR obj_seg_grp {obj_component} obj_modtail
obj_seg_grp:: {obj_LNAMES | obj_SEGDEF | obj_EXTDEF | obj_GRPDEF}
{obj_TYPDEF | obj_EXTDEF | obj_GRPDEF}
obj_component:: obj_data | obj_debug_record
obj_data:: obj_content_def | obj_thread_def | obj_COMDEF |
obj_TYPDEF | obj_PUBDEF | obj_EXTDEF |
obj_FORREF | obj_MODPUB | obj_MODEXT
obj_debug_record:: obj_LINNUM
obj_content_def:: obj_data_record {obj_FIXUPP}
obj_thread_def:: obj_FIXUPP (containing only thread fields)
obj_data_record:: obj_LIDATA | obj_LEDATA
obj_modtail:: obj_MODEND
*/
/*+-------------------------------------------------------------------------+
| |
| need32 |
| |
+-------------------------------------------------------------------------+*/
void Need32(void)
BeginDeclarations
EndDeclarations
BeginCode
If Current_record_header.rec_typ And 1
Then
If Not use32.val
Then
linker_error(12, "Command error:\n"
"\tModule: \"%s\"\n"
"\t File: \"%s\"\n"
"\tOffset: %08lX\n"
"\t Error: 32-bit records disabled.\n"
"\t Try again with Use32 switch.\n",
(*tmodule_name).symbol,
(*infile.file_info).filename,
current_record_offset);
EndIf
EndIf
EndCode
/*+-------------------------------------------------------------------------+
| |
| obj_COMDEF |
| |
+-------------------------------------------------------------------------+*/
bit_16 obj_COMDEF()
BeginDeclarations
bit_32 element_count;
bit_32 element_size;
bit_32 enclosing_segment ;
bit_8 element_type;
bit_8 expected_type;
bit_16 len;
public_entry_ptr pub;
#define Pub (*pub)
EndDeclarations
BeginCode
If Current_record_header.rec_typ IsNot COMDEF_record
Then
return(False);
EndIf;
While obj_ptr.b8 IsNot end_of_record.b8
BeginWhile
If n_externals NotLessThan max_externals
Then
max_externals += 64 ;
externals = (public_entry_ptr_array)
reallocate_memory(externals,
(Bit_32(max_externals)+1L) *
Bit_32(sizeof(group_entry_ptr)));
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, 0);
obj_ptr.b8 += len;
obj_name_length(); /* Eat the type index. */
externals[++n_externals] = pub;
element_type = *obj_ptr.b8++;
Using element_type
BeginCase
When 0x61:
expected_type = far_communal;
element_count = obj_leaf_descriptor();
element_size = obj_leaf_descriptor();
break;
When 0x62:
expected_type = near_communal;
element_size = obj_leaf_descriptor();
element_count = 1L;
break;
Otherwise:
If element_type Exceeds 0x5F
Then
linker_error(12, "Translator error:\n"
"\tModule: \"%s\"\n"
"\t File: \"%s\"\n"
"\tOffset: %08lX\n"
"\t Error: Communal type of \"%02X\" is illegal.\n",
(*tmodule_name).symbol,
(*infile.file_info).filename,
current_record_offset,
element_type);
Else
expected_type = virtual_segment ;
enclosing_segment = element_type ;
element_size = obj_leaf_descriptor() ;
EndIf ;
EndCase;
If Pub.type_entry Is unused
Then
Insert pub AtEnd InList external_list EndInsert;
Pub.type_entry = expected_type;
Pub.Communal.element_size = element_size;
Pub.Communal.element_count = element_count;
Using element_type
BeginCase
When 0x61:
Pub.Communal.element_size = element_size;
Pub.Communal.element_count = element_count;
Pub.Communal.next_communal = far_communals;
far_communals = pub;
break;
When 0x62:
Pub.Communal.element_size = element_size;
Pub.Communal.element_count = element_count;
Pub.Communal.next_communal = near_communals;
near_communals = pub;
break;
Otherwise:
Pub.Virtual.element_size = element_size ;
Pub.Virtual.enclosing_segment = snames[enclosing_segment] ;
Pub.Virtual.lseg = obj_generate_segment(lookup_lname(Pub.length, Pub.symbol),
snames[enclosing_segment]->segment->class_name,
virtual_combine,
5, /* DWORD aligned */
none_lname,
0L,
0L, /* not absolute segment */
element_size);
(*Pub.Virtual.lseg).virtualseg = True ;
If n_segments NotLessThan max_segments
Then
max_segments += 64 ;
snames = (public_entry_ptr_array)
reallocate_memory(snames,
(Bit_32(max_segments)+1L) *
Bit_32(sizeof(group_entry_ptr)));
EndIf;
Pub.Virtual.next_virtual = virtual_segs ;
snames[Pub.Virtual.seg_index = ++n_segments] = Pub.Virtual.lseg;
virtual_segs = pub ;
EndCase;
Else
If Pub.type_entry Is expected_type
Then
If expected_type Is virtual_segment
Then
If element_size IsNot Pub.Virtual.element_size
Then
linker_error(4, "Translator error:\n"
"\tModule: \"%s\"\n"
"\t File: \"%s\"\n"
"\tOffset: %08lX\n"
"\t Error: virtual segment \"%s\" "
"is a different size..\n",
(*tmodule_name).symbol,
(*infile.file_info).filename,
current_record_offset,
Pub.symbol);
EndIf ;
snames[Pub.Virtual.seg_index = ++n_segments] = Pub.Virtual.lseg;
Else
If (element_size * element_count) Exceeds
(Pub.Communal.element_size * Pub.Communal.element_count)
Then /* We need the largest common */
Pub.Communal.element_size = element_size;
Pub.Communal.element_count = element_count;
EndIf;
EndIf ;
Else
If (Pub.type_entry Is near_communal) OrIf
(Pub.type_entry Is far_communal) OrIf
(Pub.type_entry Is virtual_segment)
Then
linker_error(4, "Translator error:\n"
"\tModule: \"%s\"\n"
"\t File: \"%s\"\n"
"\tOffset: %08lX\n"
"\t Error: Communal \"%s\" is declared both near "
"and far.\n",
(*tmodule_name).symbol,
(*infile.file_info).filename,
current_record_offset,
Pub.symbol);
EndIf;
EndIf;
EndIf;
EndWhile;
obj_next_record();
return(True);
EndCode
#undef Pub
/*+-------------------------------------------------------------------------+
| |
| Import |
| |
+-------------------------------------------------------------------------+*/
void Import(void)
BeginDeclarations
bit_16 len;
public_entry_ptr pub;
#define Pub (*pub)
bit_16 ordflag ;
string_ptr tstr ;
#define Tstr (*tstr)
EndDeclarations
BeginCode
If n_imports NotLessThan max_imports
Then
max_imports += 64 ;
imports = (public_entry_ptr_array)
reallocate_memory(imports,
(Bit_32(max_imports)+1L) *
Bit_32(sizeof(group_entry_ptr)));
EndIf;
ordflag = *obj_ptr.b8++ ;
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, 0);
obj_ptr.b8 += len;
If Pub.type_entry Is internal AndIf (Pub.type_qualifier Is public_normal OrIf Pub.type_qualifier Is public_import)
Then
linker_error(-1, "Duplicate definition of public \"%s\" in module \"%s\". \n",
unmangle(Pub.symbol),
(*tmodule_name).symbol);
obj_ptr.b8 += obj_name_length() ;
If ordflag
Then
obj_ptr.b16++ ;
Else
obj_ptr.b8 += obj_name_length() ;
EndIf ;
Else
If Pub.type_entry IsNot internal
Then
len = obj_name_length();
If case_ignore.val
Then
far_to_lower(BytePtr(obj_ptr.b8), len);
EndIf;
tstr = allocate_string(len);
Tstr.length = len ;
memcpy(Tstr.text,obj_ptr.b8,len) ;
obj_ptr.b8 += len ;
Pub.moduleident = tstr ;
If ordflag
Then
Pub.ordinal = *obj_ptr.b16++ ;
Pub.entryident = NULL ;
obj_ptr.b16++;
Else
Pub.ordinal = 0 ;
len = obj_name_length();
If len IsNotZero
Then
If case_ignore.val
Then
far_to_lower(BytePtr(obj_ptr.b8), len);
EndIf;
tstr = allocate_string(len);
Tstr.length = len ;
memcpy(Tstr.text,obj_ptr.b8,len) ;
obj_ptr.b8 += len ;
Pub.entryident = tstr ;
Else
Pub.entryident = NULL ;
EndIf ;
EndIf ;
If (Pub.type_entry Is public_in_library) AndIf
(Pub.Library.requested)
Then
library_request_count--;
(*Pub.Library.lib_file).request_count--;
EndIf;
Pub.type_entry = internal ;
Pub.use_count = 0 ;
Pub.type_qualifier = public_import;
imports[n_imports++] = pub ;
Else /* If it already exists as something else, leave it */
obj_ptr.b8 += obj_name_length() ;
If ordflag
Then
obj_ptr.b16++ ;
Else
obj_ptr.b8 += obj_name_length() ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -