📄 order.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 <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"
/* ORDER.C */
/*
order_expression:: term {('or' | '+' | '|') term}
term:: factor {('and' | '*' | '&') factor}
factor:: ('!' | '~' | '-' | 'not')* primary
primary:: 'true' |
'false' |
('segment' '[' name ']' ) |
('class' '[' name ']' ) |
('group' '[' name ']' ) |
( '(' order_expression ')' )
*/
/*+-------------------------------------------------------------------------+
| |
| align_active_segment |
| |
+-------------------------------------------------------------------------+*/
void align_active_segment()
BeginDeclarations
bit_32 gap;
lseg_ptr lseg;
#define Lseg (*lseg)
bit_32 mask;
public_entry_ptr pub;
#define Pub (*pub)
EndDeclarations
BeginCode
If (*Active_segment.lsegs.first).align IsZero
Then /* Don't align absolute segments */
return;
EndIf;
Active_segment.highest_uninitialized_byte = 0L;
If pefile.val IsTrue
Then
Active_segment.pe_section_number = n_pe_sections ;
Else
Active_segment.pe_section_number = n_lx_sections ;
EndIf ;
TraverseList(Active_segment.lsegs, lseg)
BeginTraverse
LoopIf(Lseg.align Is absolute_segment);
If Active_segment.combine Is common_combine
Then /* Finally, we know how big the common area is, so allocate
memory for it. */
Lseg.data = allocate_memory(Lseg.length);
EndIf;
mask = align_mask[Lseg.align];
gap = AlignmentGap(next_available_address, mask);
next_available_address += gap;
Lseg.address = next_available_address;
next_available_address += Lseg.length;
If Lseg.highest_uninitialized_byte IsNotZero
Then
highest_uninitialized_byte =
Active_segment.highest_uninitialized_byte =
Lseg.address + Lseg.highest_uninitialized_byte;
EndIf;
EndTraverse;
Active_segment.address = (*Active_segment.lsegs.first).address;
Active_segment.length = (*Active_segment.lsegs.last).address +
(*Active_segment.lsegs.last).length -
Active_segment.address;
If Active_segment.highest_uninitialized_byte IsZero
Then
Active_segment.highest_uninitialized_byte =
(*Active_segment.lsegs.first).address;
EndIf;
If (Active_segment.owning_group IsNotNull) AndIf
((*Active_segment.owning_group).first_segment IsNull)
Then
(*Active_segment.owning_group).first_segment = active_segment;
EndIf;
If (DOSSEG.val IsTrue) AndIf
(Active_segment.owning_group IsNotNull) AndIf
((*Active_segment.owning_group).group_name Is DGROUP_lname)
Then
If (edata_segment IsNull) AndIf
(Active_segment.class_name Is BSS_lname)
Then
edata_segment = active_segment;
pub = lookup_public(6, (byte *) "_edata", 0);
If (Pub.type_entry Is external) OrIf (Pub.type_entry Is unused)
Then
Pub.type_entry = internal;
Pub.Internal.group = Active_segment.owning_group;
Pub.Internal.lseg = Active_segment.lsegs.first;
Pub.Internal.frame = 0;
Pub.Internal.offset = 0;
Else
linker_error(4, "Could not generate symbol \"_edata\" "
"when \"/DOSSEG\" set\n"
"because it was explicitly defined.\n");
EndIf;
EndIf;
If (end_segment IsNull) AndIf
(Active_segment.class_name Is STACK_lname)
Then
end_segment = active_segment;
pub = lookup_public(4, (byte *) "_end", 0);
If (Pub.type_entry Is external) OrIf (Pub.type_entry Is unused)
Then
Pub.type_entry = internal;
Pub.Internal.group = Active_segment.owning_group;
Pub.Internal.lseg = Active_segment.lsegs.first;
Pub.Internal.frame = 0;
Pub.Internal.offset = 0;
Else
linker_error(4, "Could not generate symbol \"_end\" "
"when \"/DOSSEG\" set\n"
"because it was explicitly defined.\n");
EndIf;
EndIf;
EndIf;
return;
EndCode
#undef Lseg
#undef Pub
/*+-------------------------------------------------------------------------+
| |
| pe_align_object |
| |
+-------------------------------------------------------------------------+*/
void pe_align_object(void)
BeginDeclarations
bit_32 k;
bit_32 sectNum ;
bit_32 flags ;
bit_32_ptr sectptr ;
pe_section_ptr sect;
byte_ptr name ;
byte buf[9] ;
#define Sect (*sect)
EndDeclarations
BeginCode
Using n_pe_sections
BeginCase
When 0:
flags=WINF_CODE | WINF_EXECUTE | WINF_READABLE | WINF_NEG_FLAGS;
name = "CODE\0\0\0\0" ;
sectptr = &PE_code_seg ;
break ;
When 1:
flags = WINF_INITDATA | WINF_READABLE | WINF_WRITEABLE | WINF_NEG_FLAGS;
name = "DATA\0\0\0\0" ;
sectptr = &PE_data_seg ;
break ;
When 2:
flags = WINF_INITDATA | WINF_READABLE | WINF_WRITEABLE | WINF_NEG_FLAGS;
name = "BSS\0\0\0\0\0" ;
sectptr = &PE_bss_seg ;
break ;
Otherwise:
flags = WINF_INITDATA | WINF_READABLE | WINF_WRITEABLE | WINF_NEG_FLAGS;
name = buf ;
sprintf(name,"SEG%03d\0\0",n_pe_sections) ;
sectptr = Null ;
break ;
EndCase ;
sectNum = createOutputSection(name, flags) ;
If sectptr IsNotNull Then
*sectptr = sectNum ;
EndIf ;
sect = outList[sectNum] ;
Sect.initlength = Sect.length = next_available_address - first_pe_section_address ;
Sect.virtualSize = (Sect.length + objectAlign.val -1 ) & ~(objectAlign.val-1);
Sect.base = first_pe_section_address ;
first_pe_section_address = next_available_address =
(next_available_address + objectAlign.val - 1) & ~(objectAlign.val -1) ;
EndCode
#undef Sect
/*+-------------------------------------------------------------------------+
| |
| lx_align_object |
| |
+-------------------------------------------------------------------------+*/
void lx_align_object(void)
BeginDeclarations
bit_32 k;
bit_32 sectNum ;
bit_32 flags ;
bit_32_ptr sectptr ;
lx_section_ptr sect;
byte buf[9] ;
bit_32 type = n_lx_sections ;
#define Sect (*sect)
EndDeclarations
BeginCode
Using n_lx_sections
BeginCase
When 0:
flags= LX_OF_READABLE | LX_OF_EXECUTABLE | LX_OF_BIGDEFAULT ;
sectptr = &PE_code_seg ;
break ;
When 1:
flags= LX_OF_READABLE | LX_OF_WRITEABLE | LX_OF_BIGDEFAULT ;
sectptr = &PE_data_seg ;
break ;
When 2:
flags= LX_OF_READABLE | LX_OF_WRITEABLE | LX_OF_BIGDEFAULT | LX_OF_ZEROFILL ;
sectptr = &PE_bss_seg ;
break ;
When 3:
flags= LX_OF_READABLE | LX_OF_WRITEABLE | LX_OF_BIGDEFAULT | LX_OF_ZEROFILL ;
sectptr = &lx_stack_seg ;
break ;
Otherwise:
flags= LX_OF_READABLE | LX_OF_WRITEABLE | LX_OF_BIGDEFAULT ;
sectptr = Null ;
break ;
EndCase ;
sectNum = createLXOutputSection(flags) ;
If sectptr IsNotNull
Then
*sectptr = sectNum ;
EndIf ;
sect = lx_outList[sectNum] ;
If type Is 3
Then
type = next_available_address - first_pe_section_address ;
Sect.initlength = Sect.length = type > stackSize.val ? type : stackSize.val ;
Else
Sect.initlength = Sect.length = next_available_address - first_pe_section_address ;
EndIf
Sect.virtualSize = (Sect.length + lx_page_size.val -1 ) & ~(lx_page_size.val-1);
Sect.base = first_pe_section_address ;
first_pe_section_address = next_available_address =
(next_available_address + lx_page_size.val - 1) & ~(lx_page_size.val -1) ;
EndCode
#undef Sect
/*+-------------------------------------------------------------------------+
| |
| get_order_token |
| |
+-------------------------------------------------------------------------+*/
void get_order_token()
BeginDeclarations
EndDeclarations
BeginCode
While token_break_char Is ' '
BeginWhile
order_token_get_char();
EndWhile;
copy_string(token, null_string);
If IsIdentifier(token_break_char)
Then
While IsIdentifier(token_break_char)
BeginWhile
concat_char_to_string(token, token_break_char);
order_token_get_char();
EndWhile;
lowercase_string(token);
Else
If token_break_char Is '['
Then
While token_break_char IsNot ']'
BeginWhile
concat_char_to_string(token, token_break_char);
order_token_get_char();
EndWhile;
order_token_get_char();
If case_ignore.val
Then
lowercase_string(token);
EndIf;
Else
concat_char_to_string(token, token_break_char);
order_token_get_char();
EndIf;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -