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

📄 fixup.c

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

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            fixup_FIXUPP_record                          |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void fixup_FIXUPP_record()
BeginDeclarations
byte_ptr                               byte_location;
int_32                                 IP_distance_to_target;
bit_16                                 fbval;
bit_32                                 foval;
bit_32                                 frame_address;
bit_32                                 location_address;
bit_32                                 target_address;
bit_16                                *word_location;
bit_32                                *dword_location;
bit_32                                 fixup32;
public_entry_ptr                       import ;
EndDeclarations
BeginCode
 far_move(Addr(fixup),BytePtr((*fixup_temp).data), sizeof(fixup)) ;
 frame_address  = frame();
 target_address = target(&import);
 location_address = (*(*fixup_temp).lseg).address +
                    Bit_32((*fixup_temp).offset) ;
 byte_location  = 
              Addr((*(*fixup_temp).lseg).data[(*fixup_temp).offset]);

 If import
  Then
   If lxfile.val IsTrue OrIf lefile.val IsTrue
    Then
   	   linker_error(4, "Fixup error:\n"
                   "\t Module:  \"%s\"\n"
                   "\t   File:  \"%s\"\n"
                   "\tSegment:  \"%s\"\n"
                   "\t Offset:  %08X\n"
                   "\t  Error:  Invalid fixup reference to import in LX file.\n",
                   (*(*(*fixup_temp).lseg).tmodule).symbol,
                   (*(*(*fixup_temp).lseg).file).filename,
                (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol,
                   (*fixup_temp).offset);
    EndIf ;
   If pefile.val IsTrue
    Then
     If fixup.mode IsNotZero 
        OrIf fixup.location_type IsNotEqualTo offset32_location 
             AndIf fixup.location_type IsNotEqualTo secondary_offset32_location
		  Then
#ifdef XXXXX
   	   linker_error(4, "Fixup error:\n"
                   "\t Module:  \"%s\"\n"
                   "\t   File:  \"%s\"\n"
                   "\tSegment:  \"%s\"\n"
                   "\t Offset:  %08X\n"
                   "\t  Error:  Invalid fixup reference to import.\n",
                   (*(*(*fixup_temp).lseg).tmodule).symbol,
                   (*(*(*fixup_temp).lseg).file).filename,
                (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol,
                   (*fixup_temp).offset);
#endif
				// relies on data not being relocated between now and when imports are applied
            enter_pe_import_fixup(byte_location, location_address, import,1) ;
      Else                                 	
				// relies on data not being relocated between now and when imports are applied
            enter_pe_import_fixup(byte_location, location_address, import,0) ;
      EndIf ;
    Else
	   linker_error(4, "Fixup error:\n"
                   "\t Module:  \"%s\"\n"
                   "\t   File:  \"%s\"\n"
                   "\tSegment:  \"%s\"\n"
                   "\t Offset:  %08X\n"
                   "\t  Error:  Import fixup needs a PE file.\n",
                   (*(*(*fixup_temp).lseg).tmodule).symbol,
                   (*(*(*fixup_temp).lseg).file).filename,
                (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol,
                   (*fixup_temp).offset);
    EndIf
   return ;
  EndIf ;
 If ((target_address LessThan frame_address) OrIf
     (target_address Exceeds (frame_address + 65535L)) AndIf
		 Not use32.val) AndIf
    (fixup.frame_method IsNot 6) AndIf (frame_absolute IsFalse)
  Then
   linker_error(4, "Fixup error:\n"
                   "\t Module:  \"%s\"\n"
                   "\t   File:  \"%s\"\n"
                   "\tSegment:  \"%s\"\n"
                   "\t Offset:  %08X\n"
                   "\t  Error:  Target not within frame.\n",
                   (*(*(*fixup_temp).lseg).tmodule).symbol,
                   (*(*(*fixup_temp).lseg).file).filename,
                (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol,
                   (*fixup_temp).offset);
  EndIf
 
				
 word_location  = (bit_16     *) byte_location;
 dword_location = (bit_32     *) byte_location;
 If fixup.mode IsZero
  Then /* Self-relative fixup */
   Using fixup.location_type
    BeginCase
     When lobyte_location:
      location_address ++ ;
      IP_distance_to_target = Int_32(target_address) -
                              Int_32(location_address);
      If (IP_distance_to_target < -128L) OrIf
         (IP_distance_to_target > 127L)
       Then
        linker_error(4, "Byte self-relative fixup error:\n"
                        "\t Module:  \"%s\"\n"
                        "\t   File:  \"%s\"\n"
                        "\tSegment:  \"%s\"\n"
                        "\t Offset:  %08X\n"
                        "\t  Error:  Distance to target out of range.\n",
                        (*(*(*fixup_temp).lseg).tmodule).symbol,
                        (*(*(*fixup_temp).lseg).file).filename,
                (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol,
                        (*fixup_temp).offset);
       EndIf;
      *byte_location += Bit_8(IP_distance_to_target);
      break;
     When offset_location:
     When secondary_offset_location:
      location_address += 2; 
      IP_distance_to_target = target_address - location_address;
      *word_location += Bit_16(IP_distance_to_target);
      break;
     When base_location:       /* Undefined action */
     When pointer_location:    /* Undefined action */
     When hibyte_location:     /* Undefined action */
      break;
     When offset32_location:
     When secondary_offset32_location:
			location_address += 4 ;
      IP_distance_to_target = Int_32(target_address) - Int_32(location_address);
      *dword_location += IP_distance_to_target;
      break;
    EndCase;
  Else /* Segment-relative fixup */
   enter_pe_fixup(location_address,fixup.location_type) ;
   enter_lx_fixup(target_address+*dword_location,location_address,fixup.location_type) ;
   fbval          = Bit_16(frame_address ShiftedRight 4);
   If pefile.val IsTrue OrIf lxfile.val IsTrue OrIf lefile.val IsTrue
      Then
   		foval          = target_address;
    Else
         foval          = target_address - frame_address;
      EndIf ;
   If (frame_absolute IsFalse)                     AndIf
      (exefile IsFalse)                            AndIf
      ((fixup.location_type Is base_location)      OrIf
       (fixup.location_type Is pointer_location))
    Then  /* Count the relocation items we should not be getting. */
     n_relocation_items++;
    EndIf;
   Using fixup.location_type
    BeginCase
     When lobyte_location:
      *byte_location += Bit_8(foval);
      break;
     When secondary_offset_location:
     When offset_location:
      *word_location += Bit_16(foval);
      break;
     When secondary_offset32_location:
     When offset32_location:
      *dword_location += foval;
      break;
     When base_location:
      *word_location += fbval;
      If exefile IsTrue
       Then
        Exe_header.relocation_table[Exe_header.n_relocation_items++] =
         segment_offset((*fixup_temp).lseg, (*fixup_temp).offset);
       EndIf;
      break;
     When pointer_location:
      *word_location++ += Bit_16(foval);
      *word_location   += fbval;
      If exefile IsTrue
       Then
        Exe_header.relocation_table[Exe_header.n_relocation_items++] =
         segment_offset((*fixup_temp).lseg, (*fixup_temp).offset+2);
       EndIf;
      break;
     When hibyte_location:
      *byte_location += Bit_8(foval ShiftedRight 8);
      break;
    EndCase;
  EndIf;
 return;
EndCode

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           fixup_FORREF_record                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void fixup_FORREF_record()
BeginDeclarations
bit_16                                 len;
lseg_ptr                               lseg;
#define Lseg                           (*lseg)
bit_32                                 offset;
bit_32                                 value;
bit_8                                  size;
bit_32                                 forref32;
EndDeclarations
BeginCode
 lseg          = (*fixup_temp).lseg;
 len           = (*fixup_temp).rec_len;
 far_move( BytePtr(object_file_element), (*fixup_temp).data, len) ;
 obj_ptr.b8       = object_file_element;
 end_of_record.b8 = Addr(obj_ptr.b8[len]);
 size             = *obj_ptr.b8++;
 forref32 = (*fixup_temp).rec_typ & 1;

 Using size
  BeginCase
   When 0:
    While obj_ptr.b8 IsNot end_of_record.b8
     BeginWhile
      If forref32
       Then
        offset = *obj_ptr.b32++;
        value  = *obj_ptr.b32++;
       Else
        offset = *obj_ptr.b16++;
        value  = *obj_ptr.b16++;
       EndIf
      Lseg.data[offset] += value And 0xff;
			enter_pe_fixup(Lseg.address + offset , lobyte_location) ;
     EndWhile;
    break;
   When 1:
    While obj_ptr.b8 IsNot end_of_record.b8
     BeginWhile
      If forref32
       Then
        offset = *obj_ptr.b32++;
        value  = *obj_ptr.b32++;
       Else
        offset = *obj_ptr.b16++;
        value  = *obj_ptr.b16++;
       EndIf
      *((bit_16     *) Addr(Lseg.data[offset])) += value And 0xffff;
			enter_pe_fixup(Lseg.address + offset , offset_location) ;
     EndWhile;
    break;
   When 2: /* should only be allowed for 32-bit records, but, don't know
            * how to put an error here - DAL
            */
    While obj_ptr.b8 IsNot end_of_record.b8
     BeginWhile
      If forref32
       Then
        offset = *obj_ptr.b32++;
        value  = *obj_ptr.b32++;
       Else
        offset = *obj_ptr.b16++;
        value  = *obj_ptr.b16++;
       EndIf
      *((bit_32     *) Addr(Lseg.data[offset])) += value;
			enter_pe_fixup(Lseg.address + offset , offset32_location) ;
     EndWhile;
    break;
   Otherwise:
    linker_error(4, "Translator error:\n"
                    "\t Module:  \"%s\"\n"
                    "\t   File:  \"%s\"\n"
                    "\tSegment:  \"%s\"\n"
                    "\t  Error:  Invalid FORREF record.\n",
                    (*(*(*fixup_temp).lseg).tmodule).symbol,
                    (*(*(*fixup_temp).lseg).file).filename,
            (*(*(*(*fixup_temp).lseg).segment).segment_name).symbol);
    break;
  EndCase;
 return;
EndCode
#undef Lseg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                           fixup_LEDATA_record                           |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void fixup_LEDATA_record()
BeginDeclarations
lseg_ptr                               lseg;
#define Lseg                           (*lseg)
EndDeclarations
BeginCode
 lseg          = (*fixup_temp).lseg;
// if (strstr(lseg->segment->segment_name->symbol,"Ted@Paint"))
// 	printf("bye") ;
 lseg_data_ptr = Addr(Lseg.data[(*fixup_temp).offset]);
 far_move(lseg_data_ptr, (*fixup_temp).data, (*fixup_temp).rec_len) ;
 return;
EndCode
#undef Lseg

/*+-------------------------------------------------------------------------+
  |                                                                         |
  |                            fixup_LIDATA_IDB                             |
  |                                                                         |
  +-------------------------------------------------------------------------+*/
void fixup_LIDATA_IDB()
BeginDeclarations
bit_16                                 block_count;
bit_8                                 *content;
bit_16                                 i;
bit_16                                 j;
bit_16                                 len;
bit_16                                 repeat_count;
EndDeclarations
BeginCode
 repeat_count = *obj_ptr.b16++;
 block_count  = *obj_ptr.b16++;
 If block_count IsNotZero
  Then  /* Handle recursive case:  Content is iterated data block */
   content = obj_ptr.b8;
   For i=0; i<repeat_count; i++
    BeginFor
     obj_ptr.b8 = content;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -