home *** CD-ROM | disk | FTP | other *** search
- unit reloc;
- { unit to print relocation records }
-
- interface
- uses dump,util,globals,loader,nametype,head;
-
- type
- reloc_ptr = ^reloc_rec;
- reloc_rec = record
- unit_num, { offset to unit in unit block }
- rtype : byte;
- rblock,roffset,offset : word;
- end;
-
- const
- code_seg = 0;
- code_data = 1;
- var_seg = 2;
- const_seg = 3;
-
- procedure print_reloc(seg:byte);
- procedure write_reloc_type(rtype:byte);
-
- implementation
-
- uses
- blocks;
-
- function ref_type(rtype:byte):byte;
- begin
- ref_type := (rtype shr 4) and 3;
- end;
-
- function target_type(rtype:byte):byte;
- begin
- target_type := rtype shr 6;
- end;
-
- procedure print_reloc(seg:byte);
- var
- codebase,codeofs,codelimit,
- base,ofs,limit : word;
- block : reloc_ptr;
- code_block : block_ptr;
- target_unit : unit_list_ptr;
- entry_pt : entry_pt_ptr;
- target_unit_name : string;
- fake_unit_info : unit_ptr;
- begin
- writeln;
- case seg of
- code_seg : begin
- writeln('Code segment relocation records');
- if header^.reloc_size = 0 then
- begin
- writeln('(none)');
- exit;
- end;
- codebase :=header^.ofs_code_blocks;
- codelimit := header^.ofs_const_blocks-codebase;
- end;
-
- const_seg : begin
- writeln('Const segment relocation records');
- if header^.vmt_size = 0 then
- begin
- writeln('(none)');
- exit;
- end;
- codebase :=header^.ofs_const_blocks;
- codelimit := header^.ofs_var_blocks-codebase;
- end;
- end;
- writeln(' Reloc');
- writeln(' Offset Fixup Type Unit Block:Offset');
- base := 0;
- codeofs := 0;
- while codeofs < codelimit do
- begin
- code_block := add_offset(buffer,codebase+codeofs);
- write('---');
- case seg of
- code_seg: write_code_block_name(code_block^.owner);
- const_seg: write_const_block_name(code_block^.owner);
- end;
- writeln('---');
- ofs := 0;
- limit := code_block^.relocbytes;
- while ofs < limit do
- begin
- block := add_offset(reloc_buf,base+ofs);
- with block^ do
- begin
- write(hexword2(codeofs),':',hexword(offset),' ');
- if (rtype = $FF) and (unit_num = $FF) then
- begin
- write('Coproc ');
- case rblock of
- 1 : write('DS override');
- 2 : write('SS override');
- 3 : write('CS override');
- 4 : write('ES override');
- 5 : write('Standard');
- 6 : write('FWAIT');
- else
- write('Unrecognized fixup type ',hexword(rblock));
- end;
- if roffset <> 0 then
- write(' ROffset = ',hexword(Roffset));
- end
- else
- begin
- write_reloc_type(rtype);
- target_unit_name := unit_name(unit_num);
- write(target_unit_name:10);
-
- if target_type(rtype) = 0 then { This doesn't catch Coproc fixups }
- begin
- { It might be a good idea to try to add the unit to the unit_list
- here, but I don't think so. Let it fail if it wants to. }
-
- target_unit := get_unit_by_name(target_unit_name);
-
- if (target_unit <> nil) and (target_unit^.buffer <> nil) then
- with target_unit^ do
- begin
- entry_pt := add_offset(buffer,
- header_ptr(buffer)^.ofs_entry_pts+rblock);
- write(' ',hexword2(entry_pt^.code_block),':',
- hexword(entry_pt^.offset));
- end
- else
- write(' entry',hexword(rblock));
- end
- else
- write(' ',hexword2(rblock),':',hexword(roffset));
- end;
- writeln;
- end;
- inc(ofs,sizeof(reloc_rec));
- end;
- inc(base,ofs);
- inc(codeofs,sizeof(block_rec));
- end;
- end;
-
- procedure write_reloc_type(rtype:byte);
- begin
- if (rtype and $0F) <> 0 then
- write ('Unknown type ',hexbyte(rtype):4);
-
- case ref_type(rtype) of
- 0 : write('Relative ');
- 1 : write('Offset ');
- 2 : write('Segment ');
- 3 : write('Pointer ');
- end;
-
- case target_type(rtype) of
- code_seg : write('Code ');
- code_data : write('CS Const');
- var_seg : write('Var ');
- const_seg : write('DS Const');
- end;
- end;
-
- end.