📄 vms.c
字号:
* Text Psect. */ VMS_Set_Psect(Text_Psect,fragP->fr_address,OBJ$C_TIR); /* * Store the "fixed" part */ if (fragP->fr_fix) VMS_Store_Immediate_Data(fragP->fr_literal, fragP->fr_fix, OBJ$C_TIR); /* * Store the "variable" part */ if (fragP->fr_var && fragP->fr_offset) VMS_Store_Repeated_Data(fragP->fr_offset, fragP->fr_literal+ fragP->fr_fix, fragP->fr_var, OBJ$C_TIR); } /* * Now we go through the text segment fixups and * generate TIR records to fix up addresses within * the Text Psect */ for(fixP = text_fix_root; fixP; fixP = fixP->fx_next) { /* * We DO handle the case of "Symbol - Symbol" as * long as it is in the same segment. */ if (fixP->fx_subsy && fixP->fx_addsy) { int i; /* * They need to be in the same segment */ if (fixP->fx_subsy->sy_type != fixP->fx_addsy->sy_type) error("Fixup data addsy and subsy didn't have the same type"); /* * And they need to be in one that we * can check the psect on */ if (((fixP->fx_addsy->sy_type & ~N_EXT) != N_DATA) && ((fixP->fx_addsy->sy_type & ~N_EXT) != N_TEXT)) error("Fixup data addsy and subsy didn't have an appropriate type"); /* * This had better not be PC relative! */ if (fixP->fx_pcrel) error("Fixup data was erroneously \"pcrel\""); /* * Subtract their values to get the * difference. */ i = fixP->fx_addsy->sy_value - fixP->fx_subsy->sy_value; /* * Now generate the fixup object records * Set the psect and store the data */ VMS_Set_Psect(Text_Psect, fixP->fx_where + fixP->fx_frag->fr_address, OBJ$C_TIR); VMS_Store_Immediate_Data(&i, fixP->fx_size, OBJ$C_TIR); /* * Done */ continue; } /* * Size will HAVE to be "long" */ if (fixP->fx_size != sizeof(long)) error("Fixup datum was not a longword"); /* * Symbol must be "added" (if it is ever * subtracted we can * fix this assumption) */ if (fixP->fx_addsy == 0) error("Fixup datum was not \"fixP->fx_addsy\""); /* * Store the symbol value in a PIC fashion */ VMS_Store_PIC_Symbol_Reference(fixP->fx_addsy, fixP->fx_offset, fixP->fx_pcrel, Text_Psect, fixP->fx_where + fixP->fx_frag->fr_address, OBJ$C_TIR); /* * Check for indirect address reference, * which has to be fixed up (as the linker * will screw it up with TIR$C_STO_PICR). */ if (fixP->fx_pcrel) VMS_Fix_Indirect_Reference(Text_Psect, fixP->fx_where + fixP->fx_frag->fr_address, fixP->fx_frag, text_frag_root); } } /* * Store the Data segment: * * Since this is REALLY hard to do any other way, * we actually manufacture the data segment and * the store the appropriate values out of it. */ if (data_siz > 0) { char *Data_Segment; /* * Allocate the data segment */ Data_Segment = (char *)xmalloc(data_siz); /* * Run through the data fragments, filling in the segment */ for(fragP = data_frag_root; fragP; fragP = fragP->fr_next) { register long int count; register char * fill_literal; register long int fill_size; int i; i = fragP->fr_address - text_siz; if (fragP->fr_fix) bcopy(fragP->fr_literal, Data_Segment + i, fragP->fr_fix); i += fragP->fr_fix; fill_literal= fragP -> fr_literal + fragP -> fr_fix; fill_size = fragP -> fr_var; for (count = fragP -> fr_offset; count; count --) { if (fill_size) bcopy(fill_literal, Data_Segment + i, fill_size); i += fill_size; } } /* * Now we can run through all the data symbols * and store the data */ for(vsp = VMS_Symbols; vsp; vsp = vsp->Next) { /* * Ignore anything other than data symbols */ if ((vsp->Symbol->sy_nlist.n_type & ~N_EXT) != N_DATA) continue; /* * Set the Psect + Offset */ VMS_Set_Psect(vsp->Psect_Index, vsp->Psect_Offset, OBJ$C_TIR); /* * Store the data */ VMS_Store_Immediate_Data(Data_Segment + vsp->Symbol->sy_nlist.n_value - text_siz, vsp->Size, OBJ$C_TIR); } /* * Now we go through the data segment fixups and * generate TIR records to fix up addresses within * the Data Psects */ for(fixP = data_fix_root; fixP; fixP = fixP->fx_next) { /* * Find the symbol for the containing datum */ for(vsp = VMS_Symbols; vsp; vsp = vsp->Next) { /* * Only bother with Data symbols */ sp = vsp->Symbol; if ((sp->sy_nlist.n_type & ~N_EXT) != N_DATA) continue; /* * Ignore symbol if After fixup */ if (sp->sy_nlist.n_value > (fixP->fx_where + fixP->fx_frag->fr_address)) continue; /* * See if the datum is here */ if ((sp->sy_nlist.n_value + vsp->Size) <= (fixP->fx_where + fixP->fx_frag->fr_address)) continue; /* * We DO handle the case of "Symbol - Symbol" as * long as it is in the same segment. */ if (fixP->fx_subsy && fixP->fx_addsy) { int i; /* * They need to be in the same segment */ if (fixP->fx_subsy->sy_type != fixP->fx_addsy->sy_type) error("Fixup data addsy and subsy didn't have the same type"); /* * And they need to be in one that we * can check the psect on */ if (((fixP->fx_addsy->sy_type & ~N_EXT) != N_DATA) && ((fixP->fx_addsy->sy_type & ~N_EXT) != N_TEXT)) error("Fixup data addsy and subsy didn't have an appropriate type"); /* * This had better not be PC relative! */ if (fixP->fx_pcrel) error("Fixup data was erroneously \"pcrel\""); /* * Subtract their values to get the * difference. */ i = fixP->fx_addsy->sy_value - fixP->fx_subsy->sy_value; /* * Now generate the fixup object records * Set the psect and store the data */ VMS_Set_Psect(vsp->Psect_Index, fixP->fx_frag->fr_address + fixP->fx_where - vsp->Symbol->sy_value + vsp->Psect_Offset, OBJ$C_TIR); VMS_Store_Immediate_Data(&i, fixP->fx_size, OBJ$C_TIR); /* * Done */ break; } /* * Size will HAVE to be "long" */ if (fixP->fx_size != sizeof(long)) error("Fixup datum was not a longword"); /* * Symbol must be "added" (if it is ever * subtracted we can * fix this assumption) */ if (fixP->fx_addsy == 0) error("Fixup datum was not \"fixP->fx_addsy\""); /* * Store the symbol value in a PIC fashion */ VMS_Store_PIC_Symbol_Reference( fixP->fx_addsy, fixP->fx_offset, fixP->fx_pcrel, vsp->Psect_Index, fixP->fx_frag->fr_address + fixP->fx_where - vsp->Symbol->sy_value + vsp->Psect_Offset, OBJ$C_TIR); /* * Done */ break; } } } /* * Write the Traceback Begin Module record */ VMS_TBT_Module_Begin(); /* * Scan the symbols and write out the routines * (this makes the assumption that symbols are in * order of ascending text segment offset) */ { struct symbol *Current_Routine = 0; int Current_Line_Number = 0; int Current_Offset = -1; struct input_file * Current_File;/* Output debugging info for global variables and static variables that are not * specific to one routine. We also need to examine all stabs directives, to * find the definitions to all of the advanced data types, and this is done by * VMS_LSYM_Parse. This needs to be done before any definitions are output to * the object file, since there can be forward references in the stabs * directives. When through with parsing, the text of the stabs directive * is altered, with the definitions removed, so that later passes will see * directives as they would be written if the type were already defined. * * We also look for files and include files, and make a list of them. We * examine the source file numbers to establish the actual lines that code was * generated from, and then generate offsets. */ VMS_LSYM_Parse(); for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) { /* * Deal with STAB symbols */ if ((symbolP->sy_nlist.n_type & N_STAB) != 0) { /* * Dispatch on STAB type */ switch((unsigned char)symbolP->sy_nlist.n_type) { case N_SLINE: if(symbolP->sy_nlist.n_desc > Current_File->max_line) Current_File->max_line = symbolP->sy_nlist.n_desc; if(symbolP->sy_nlist.n_desc < Current_File->min_line) Current_File->min_line = symbolP->sy_nlist.n_desc; break; case N_SO: Current_File =find_file(symbolP); Current_File->flag = 1; Current_File->min_line = 1; break; case N_SOL: Current_File = find_file(symbolP); break; case N_GSYM: VMS_GSYM_Parse(symbolP,Text_Psect); break; case N_LCSYM: VMS_LCSYM_Parse(symbolP,Text_Psect); break; case N_FUN: /* For static constant symbols */ case N_STSYM: VMS_STSYM_Parse(symbolP,Text_Psect); break; } } } /* now we take a quick sweep through the files and assign offsets to each one. This will essentially be the starting line number to the debugger for each file. Output the info for the debugger to specify the files, and then tell it how many lines to use */ { int File_Number = 0; int Debugger_Offset = 0; int file_available; Current_File = file_root; for(Current_File = file_root; Current_File; Current_File = Current_File->next){ if(Current_File == (struct input_file*) NULL) break; if(Current_File->max_line == 0) continue; if((strncmp(Current_File->name,"GNU_GXX_INCLUDE:",16) == 0) && !flagseen['D']) continue; if((strncmp(Current_File->name,"GNU_CC_INCLUDE:",15) == 0) && !flagseen['D']) continue;/* show a few extra lines at the start of the region selected */ if(Current_File->min_line > 2) Current_File->min_line -= 2; Current_File->offset = Debugger_Offset - Current_File->min_line + 1; Debugger_Offset += Current_File->max_line - Current_File->min_line + 1; if(Current_File->same_file_fpnt != (struct input_file *) NULL) Current_File->file_number =Current_File->same_file_fpnt->file_number; else { Current_File->file_number = ++File_Number; file_available = VMS_TBT_Source_File(Current_File->name, Current_File->file_number); if(!file_available) {Current_File->file_number = 0; File_Number--; continue;}; }; VMS_TBT_Source_Lines(Current_File->file_number, Current_File->min_line, Current_File->max_line-Current_File->min_line+1); }; /* for */ }; /* scope */ Current_File = (struct input_file*) NULL; for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next) { /* * Deal with text symbols */ if ((symbolP->sy_nlist.n_type & ~N_EXT) == N_TEXT) { /* * Ignore symbols starting with "L", * as they are local symbols */ if (symbolP->sy_nlist.n_un.n_name[0] == 'L') continue; /* * If there is a routine start defined, * terminate it. */ if (Current_Routine) { /* * End the routine */ VMS_TBT_Routine_End(text_siz,Current_Routine); } /* * Store the routine begin traceback info */ if(Text_Psect != -1) { VMS_TBT_Routine_Begin(symbolP,Text_Psect); Current_Routine = symbolP; }/* Output local symbols, i.e. all symbols that are associated with a specific * routine. We output them now so the debugger recognizes them as local to * this routine. */ { symbolS * symbolP1; char* pnt; char* pnt1; for(symbolP1 = Current_Routine; symbolP1; symbolP1 = symbolP1->sy_next) { if ((symbolP1->sy_nlist.n_type & N_STAB) == 0) continue; if (symbolP1->sy_nlist.n_type != N_FUN) continue; pnt=symbolP->sy_nlist.n_un.n_name; pnt1=symbolP1->sy_nlist.n_un.n_name; if(*pnt++ != '_') continue; while(*pnt++ == *pnt1++) {}; if((*(--pnt) == '\0') && (*(--pnt1) == ':')) break; }; if(symbolP1 != (symbolS *) NULL) VMS_DBG_Define_Routine(symbolP1,Current_Routine,Text_Psect); } /* local symbol block */ /* * Done */ continue; } /* * Deal with STAB symbols */ if ((symbolP->sy_nlist.n_type & N_STAB) != 0) { /* * Dispatch on STAB type */ switch((unsigned char)symbolP->sy_nlist.n_type) { /* * Line number */ case N_SLINE: /* Offset the line into the correct portion * of the file */ if(Current_File->file_number == 0) break; /* Sometimes the same offset gets several source * lines assigned to it. * We should be selective about which lines * we allow, we should prefer lines that are * in the main source file when debugging * inline functions. */ if((Current_File->file_number != 1) && symbolP->sy_nlist.n_value == Current_Offset) break; /* calculate actual debugger source line */ symbolP->sy_nlist.n_desc += Current_File->offset; /* * If this is the 1st N_SLINE, setup * PC/Line correlation. Otherwise * do the delta PC/Line. If the offset * for the line number is not +ve we need * to do another PC/Line correlation * setup */ if (Current_Offset == -1) { VMS_TBT_Line_PC_Correlation( symbolP->sy_nlist.n_desc, symbolP->sy_nlist.n_value, Text_Psect, 0); } else { if ((symbolP->sy_nlist.n_desc - Current_Line_Number) <= 0) { /* * Line delta is not +ve, we * need to close the line and * start a new PC/Line * correlation. */ VMS_TBT_Line_PC_Correlation(0, symbolP->sy_nlist.n_value - Current_Offset, 0, -1); VMS_TBT_Line_PC_Correlation( symbolP->sy_nlist.n_desc, symbolP->sy_nlist.n_value, Text_Psect, 0); } else { /* * Line delta is +ve, all is well */ VMS_TBT_Line_PC_Correlation( symbolP->sy_nlist.n_desc - Current_Line_Number, symbolP->sy_nlist.n_value - Current_Offset, 0, 1); } } /* * Update the current line/PC */ Current_Line_Number = symbolP->sy_nlist.n_desc; Current_Offset = symbolP->sy_nlist.n_value; /* * Done */ break; /* * Source file */ case N_SO: /* * Remember that we had a source file * and emit the source file debugger * record */ Current_File = find_file(symbolP); break;/* We need to make sure that we are really in the actual source file when * we compute the maximum line number. Otherwise the debugger gets really * confused */ case N_SOL: Current_File = find_file(symbolP); break; } } } /* * If there is a routine start defined, * terminate it (and the line numbers) */ if (Current_Routine) { /* * Terminate the line numbers */ VMS_TBT_Line_PC_Correlation(0, text_siz - Current_Routine->sy_nlist.n_value, 0, -1); /* * Terminate the routine */ VMS_TBT_Routine_End(text_siz,Current_Routine); } } /* * Write the Traceback End Module TBT record */ VMS_TBT_Module_End(); /* * Write the End Of Module record */ if (Entry_Point_Symbol == 0) Write_VMS_EOM_Record(-1,0); else Write_VMS_EOM_Record(Text_Psect,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -