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

📄 tmodule.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 5 页
字号:
/* 
   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 + -