?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: VE Linker Utilites' ??
MODULE ocm$ve_linker_utilities;

{ PURPOSE:
{   Utility routines used by the VE Linker.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc llt$object_library_header
*copyc occ$symbol_table_version
*copyc oce$library_generator_errors
*copyc oce$ve_linker_exceptions
*copyc oct$known_file_list
*copyc oct$object_file_descriptor
*copyc oct$output_segment_descriptor
*copyc oct$program_name_list
*copyc oct$section_name_list
*copyc oct$segment
*copyc oct$symbol_table_descriptor
*copyc pmt$linker_debug_table_header
?? POP ??
*copyc amp$get_segment_pointer
*copyc fsp$close_file
*copyc fsp$get_open_information
*copyc fsp$open_file
*copyc osp$append_status_parameter
*copyc osp$generate_error_message
*copyc osp$set_status_abnormal
*copyc ocv$predefined_segment_list
*copyc ocv$section_name_list
*copyc ocv$vel_scratch_seq
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$search_modules_to_add', EJECT ??

  PROCEDURE [XDCL] ocp$search_modules_to_add
    (VAR modules_to_add: oct$program_name_list;
         module_name: pmt$program_name;
     VAR module_found: boolean;
     VAR module_before: ^oct$program_name_list);


    module_before := ^modules_to_add;

    WHILE (module_before^.link <> NIL) DO
      IF module_before^.link^.name = module_name THEN
        module_found := TRUE;
        RETURN;
      IFEND;

      module_before := module_before^.link;
    WHILEND;

    module_found := FALSE;


  PROCEND ocp$search_modules_to_add;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$duplicate_segment_number', EJECT ??

  FUNCTION [XDCL] ocp$duplicate_segment_number
    (    segment_number: oct$segment): boolean;


    VAR
      segment_descriptor: ^oct$output_segment_descriptor;


    segment_descriptor := ocv$predefined_segment_list.link;

    WHILE segment_descriptor <> NIL DO
      IF segment_descriptor^.number = segment_number THEN
        ocp$duplicate_segment_number := TRUE;
        RETURN;
      IFEND;

      segment_descriptor := segment_descriptor^.link;
    WHILEND;

    ocp$duplicate_segment_number := FALSE;


  FUNCEND ocp$duplicate_segment_number;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$duplicate_section_name', EJECT ??

  FUNCTION [XDCL] ocp$duplicate_section_name
    (    section_name: pmt$program_name): boolean;


    VAR
      section_name_list: ^oct$section_name_list;


    section_name_list := ocv$section_name_list.link;

    WHILE section_name_list <> NIL DO
      IF section_name_list^.name = section_name THEN
        ocp$duplicate_section_name := TRUE;
        RETURN;
      IFEND;

      section_name_list := section_name_list^.link;
    WHILEND;

    ocp$duplicate_section_name := FALSE;


  FUNCEND ocp$duplicate_section_name;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$duplicate_file', EJECT ??

  FUNCTION [XDCL] ocp$duplicate_file
    (    file_name: fst$file_reference;
         known_file_list: oct$known_file_list): boolean;


    VAR
      known_file: ^oct$known_file_list;


    known_file := ^known_file_list;

    REPEAT
      IF (known_file^.name <> NIL) AND (known_file^.name^ = file_name) THEN
        ocp$duplicate_file := TRUE;
        RETURN;
      IFEND;

      known_file := known_file^.link;
    UNTIL known_file = NIL;

    ocp$duplicate_file := FALSE;


  FUNCEND ocp$duplicate_file;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$add_to_known_files', EJECT ??

  PROCEDURE [XDCL] ocp$add_to_known_files
    (    file_name: fst$file_reference;
     VAR known_file_list: oct$known_file_list;
     VAR status: ost$status);


    VAR
      known_file: ^oct$known_file_list;


    NEXT known_file IN ocv$vel_scratch_seq;
    IF known_file = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU1', status);
      RETURN;
    IFEND;

    NEXT known_file^.name: [STRLENGTH (file_name)] IN ocv$vel_scratch_seq;
    IF known_file^.name = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU2', status);
      RETURN;
    IFEND;

    known_file^.name^ := file_name;
    known_file^.link := known_file_list.link;
    known_file_list.link := known_file;


  PROCEND ocp$add_to_known_files;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_linker_object_file', EJECT ??

  PROCEDURE [XDCL] ocp$open_linker_object_file
    (    ofd: ^oct$object_file_descriptor;
     VAR status: ost$status);


    VAR
      attachment_options: array [1 .. 2] of fst$attachment_option,
      cycle_attribute_values: fst$cycle_attribute_values,
      i: 0 .. llc$max_dictionaries_on_library,
      ignore_user_defined_attr_size: fst$user_defined_attribute_size,
      library_dictionary: ^llt$object_library_dictionaries,
      object_library_hdr: ^llt$object_library_header_v1_0,
      object_library_header: ^llt$object_library_header,
      validation_attributes: array [1 .. 2] of fst$file_cycle_attribute;


    status.normal := TRUE;

    attachment_options [1].selector := fsc$access_and_share_modes;
    attachment_options [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options [1].access_modes.value := $fst$file_access_options [fsc$read];
    attachment_options [1].share_modes.selector := fsc$determine_from_access_modes;
    attachment_options [2].selector := fsc$create_file;
    attachment_options [2].create_file := FALSE;
    validation_attributes [1].selector := fsc$file_contents_and_processor;
    validation_attributes [1].file_contents := fsc$object_library;
    validation_attributes [1].file_processor := fsc$unknown_processor;
    validation_attributes [2].selector := fsc$file_contents_and_processor;
    validation_attributes [2].file_contents := fsc$object_data;
    validation_attributes [2].file_processor := fsc$unknown_processor;

    fsp$open_file (ofd^.name^, amc$segment, ^attachment_options, {default_creation_attributes} NIL,
          {mandated_creation_attributes} NIL, ^validation_attributes, {attribute_override} NIL, ofd^.id,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    fsp$get_open_information (ofd^.id, {attachment_information} NIL, {catalog_information} NIL,
          {cycle_attribute_sources} NIL, ^cycle_attribute_values, {instance_information} NIL,
          {resolved_file_reference} NIL, {user_defined_attributes} NIL, ignore_user_defined_attr_size,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (ofd^.id, amc$sequence_pointer, ofd^.segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    ofd^.is_a_library := (cycle_attribute_values.file_contents = fsc$object_library);
    IF ofd^.is_a_library THEN
      RESET ofd^.segment.sequence_pointer;

      NEXT object_library_header IN ofd^.segment.sequence_pointer;
      IF object_library_header = NIL THEN
        osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, ofd^.name^, status);
        RETURN;
      IFEND;

      IF object_library_header^.version = llc$object_library_version THEN

        NEXT library_dictionary: [1 .. object_library_header^.number_of_dictionaries] IN
              ofd^.segment.sequence_pointer;
        IF library_dictionary = NIL THEN
          osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, ofd^.name^, status);
          RETURN;
        IFEND;

        ofd^.module_dictionary := NIL;
        ofd^.entry_point_dictionary := NIL;

        FOR i := LOWERBOUND (library_dictionary^) TO UPPERBOUND (library_dictionary^) DO
          CASE library_dictionary^ [i].kind OF
          = llc$module_dictionary =
            ofd^.module_dictionary := #PTR (library_dictionary^ [i].module_dictionary,
                  ofd^.segment.sequence_pointer^);
          = llc$entry_point_dictionary =
            ofd^.entry_point_dictionary := #PTR (library_dictionary^ [i].entry_point_dictionary,
                  ofd^.segment.sequence_pointer^);
          ELSE
          CASEND;
        FOREND;

      ELSEIF object_library_header^.version = 'V1.0' THEN
        RESET ofd^.segment.sequence_pointer;

        NEXT object_library_hdr IN ofd^.segment.sequence_pointer;
        IF object_library_hdr = NIL THEN
          osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, ofd^.name^, status);
          RETURN;
        IFEND;

        IF object_library_hdr^.number_of_modules <> 0 THEN
          ofd^.module_dictionary := #PTR (object_library_hdr^.module_dictionary,
                ofd^.segment.sequence_pointer^);
          IF ofd^.module_dictionary = NIL THEN
            osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, ofd^.name^, status);
            RETURN;
          IFEND;
        ELSE
          ofd^.module_dictionary := NIL;
        IFEND;

        IF object_library_hdr^.number_of_entry_points <> 0 THEN
          ofd^.entry_point_dictionary := #PTR (object_library_hdr^.entry_point_dictionary,
                ofd^.segment.sequence_pointer^);
          IF ofd^.entry_point_dictionary = NIL THEN
            osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, ofd^.name^, status);
            RETURN;
          IFEND;
        ELSE
          ofd^.entry_point_dictionary := NIL;
        IFEND;

      ELSE
        osp$set_status_abnormal ('OC', oce$e_invalid_library_version, object_library_header^.version, status);
        osp$append_status_parameter (osc$status_parameter_delimiter, ofd^.name^, status);
        RETURN;
      IFEND;

    IFEND;

  PROCEND ocp$open_linker_object_file;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_linker_symbol_table', EJECT ??

  PROCEDURE [XDCL] ocp$open_linker_symbol_table
    (    std: ^oct$symbol_table_descriptor;
     VAR status: ost$status);


    VAR
      attachment_options: array [1 .. 2] of fst$attachment_option,
      ignore_status: ost$status,
      validation_attributes: array [1 .. 1] of fst$file_cycle_attribute;


    status.normal := TRUE;

    attachment_options [1].selector := fsc$access_and_share_modes;
    attachment_options [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options [1].access_modes.value := $fst$file_access_options [fsc$read];
    attachment_options [1].share_modes.selector := fsc$determine_from_access_modes;
    attachment_options [2].selector := fsc$create_file;
    attachment_options [2].create_file := FALSE;
    validation_attributes [1].selector := fsc$file_contents_and_processor;
    validation_attributes [1].file_contents := fsc$data;
    validation_attributes [1].file_processor := fsc$unknown_processor;

    fsp$open_file (std^.name^, amc$segment, ^attachment_options, {default_creation_attributes} NIL,
          {mandated_creation_attributes} NIL, ^validation_attributes, {attribute_override} NIL, std^.id,
          status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (std^.id, amc$sequence_pointer, std^.segment, status);
    IF NOT status.normal THEN
      fsp$close_file (std^.id, ignore_status);
      RETURN;
    IFEND;

    RESET std^.segment.sequence_pointer;

    NEXT std^.header IN std^.segment.sequence_pointer;
    IF std^.header = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, std^.name^, status);
      fsp$close_file (std^.id, ignore_status);
      RETURN;
    IFEND;

    IF std^.header^.version <> occ$symbol_table_version THEN
      osp$set_status_abnormal ('OC', oce$e_invalid_lst_version, std^.name^, status);
      RETURN;
    IFEND;

    IF std^.header^.number_of_symbols = 0 THEN
      std^.symbol_table := NIL;

    ELSE
      NEXT std^.symbol_table: [1 .. std^.header^.number_of_symbols] IN std^.segment.sequence_pointer;
      IF std^.symbol_table = NIL THEN
        osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, std^.name^, status);
        fsp$close_file (std^.id, ignore_status);
      IFEND;
    IFEND;


  PROCEND ocp$open_linker_symbol_table;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_output_segment', EJECT ??

  PROCEDURE [XDCL] ocp$open_output_segment
    (    name: fst$file_reference;
     VAR file_identifier: amt$file_identifier;
     VAR segment: amt$segment_pointer;
     VAR status: ost$status);


    VAR
      attachment_options: ^fst$attachment_options,
      creation_validation_attributes: ^fst$file_cycle_attributes,
      ignore_status: ost$status;


    status.normal := TRUE;

    PUSH attachment_options: [1 .. 1];
    PUSH creation_validation_attributes: [1 .. 2];

    attachment_options^ [1].selector := fsc$access_and_share_modes;
    attachment_options^ [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options^ [1].access_modes.value := $fst$file_access_options
          [fsc$read, fsc$append, fsc$modify, fsc$shorten];
    attachment_options^ [1].share_modes.selector := fsc$determine_from_access_modes;

    creation_validation_attributes^ [1].selector := fsc$file_contents_and_processor;
    creation_validation_attributes^ [1].file_contents := fsc$data;
    creation_validation_attributes^ [1].file_processor := fsc$unknown_processor;
    creation_validation_attributes^ [2].selector := fsc$preset_value;
    creation_validation_attributes^ [2].preset_value := 0;

    fsp$open_file (name, amc$segment, attachment_options, {default_creation_attributes} NIL,
          creation_validation_attributes, creation_validation_attributes, {attribute_override} NIL,
          file_identifier, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (file_identifier, amc$sequence_pointer, segment, status);
    IF NOT status.normal THEN
      fsp$close_file (file_identifier, ignore_status);
      RETURN;
    IFEND;

    RESET segment.sequence_pointer;

  PROCEND ocp$open_output_segment;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_segment_for_68000', EJECT ??

  PROCEDURE [XDCL] ocp$open_segment_for_68000
    (    segment_length: ost$segment_length;
     VAR mc68000_seq: ^SEQ ( * );
     VAR segment: amt$segment_pointer;
     VAR status: ost$status);

    segment.kind := amc$sequence_pointer;
    NEXT segment.sequence_pointer: [[REP segment_length OF cell]] IN mc68000_seq;
    IF segment.sequence_pointer = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU3', status);
      RETURN;
    IFEND;


  PROCEND ocp$open_segment_for_68000;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$add_to_predefined_segments', EJECT ??

  PROCEDURE [XDCL] ocp$add_to_predefined_segments
    (    segment_descriptor: ^oct$output_segment_descriptor;
         section_names: ^oct$section_name_list;
     VAR status: ost$status);


    VAR
      segment: ^oct$output_segment_descriptor,
      section_name: ^oct$section_name_list;


    segment := ^ocv$predefined_segment_list;

    WHILE segment^.link <> NIL DO
      segment := segment^.link;
    WHILEND;

    NEXT segment^.link IN ocv$vel_scratch_seq;
    segment := segment^.link;
    IF segment = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU4', status);
      RETURN;
    IFEND;

    segment^ := segment_descriptor^;
    segment^.link := NIL;

    section_name := ^ocv$section_name_list;

    WHILE section_name^.link <> NIL DO
      section_name := section_name^.link;
    WHILEND;

    section_name^.link := section_names;

    section_name := section_name^.link;

    WHILE section_name <> NIL DO
      section_name^.segment_descriptor := segment;
      section_name := section_name^.link;
    WHILEND;


  PROCEND ocp$add_to_predefined_segments;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$add_to_object_file_list', EJECT ??

  PROCEDURE [XDCL] ocp$add_to_object_file_list
    (    ofd: ^oct$object_file_descriptor;
         object_file_list: ^oct$object_file_descriptor;
     VAR status: ost$status);


    VAR
      last_descriptor: ^oct$object_file_descriptor;


    last_descriptor := object_file_list;

    WHILE last_descriptor^.link <> NIL DO
      last_descriptor := last_descriptor^.link;
    WHILEND;

    NEXT last_descriptor^.link IN ocv$vel_scratch_seq;
    last_descriptor := last_descriptor^.link;
    IF last_descriptor = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU5', status);
      RETURN;
    IFEND;

    last_descriptor^ := ofd^;
    last_descriptor^.link := NIL;


  PROCEND ocp$add_to_object_file_list;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$close_linker_object_files', EJECT ??

  PROCEDURE [XDCL] ocp$close_linker_object_files
    (    ofd: ^oct$object_file_descriptor);


    VAR
      descriptor: ^oct$object_file_descriptor,
      status: ost$status;


    descriptor := ofd;

    WHILE descriptor <> NIL DO
      fsp$close_file (descriptor^.id, status);
      IF NOT status.normal THEN
        osp$generate_error_message (status, status);
      IFEND;

      descriptor := descriptor^.link;
    WHILEND;


  PROCEND ocp$close_linker_object_files;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$close_predefined_segments', EJECT ??

  PROCEDURE [XDCL] ocp$close_predefined_segments
    (    sd: ^oct$output_segment_descriptor);


    VAR
      descriptor: ^oct$output_segment_descriptor,
      status: ost$status;


    descriptor := sd;

    WHILE descriptor <> NIL DO
      fsp$close_file (descriptor^.id, status);
      IF NOT status.normal THEN
        osp$generate_error_message (status, status);
      IFEND;

      descriptor := descriptor^.link;
    WHILEND;


  PROCEND ocp$close_predefined_segments;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$close_linker_symbol_tables', EJECT ??

  PROCEDURE [XDCL] ocp$close_linker_symbol_tables
    (    std: ^oct$symbol_table_descriptor);


    VAR
      descriptor: ^oct$symbol_table_descriptor,
      status: ost$status;


    descriptor := std;

    WHILE descriptor <> NIL DO
      fsp$close_file (descriptor^.id, status);
      IF NOT status.normal THEN
        osp$generate_error_message (status, status);
      IFEND;

      descriptor := descriptor^.link;
    WHILEND;


  PROCEND ocp$close_linker_symbol_tables;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$add_to_symbol_table_list', EJECT ??

  PROCEDURE [XDCL] ocp$add_to_symbol_table_list
    (    std: ^oct$symbol_table_descriptor;
         symbol_table_list: ^oct$symbol_table_descriptor;
     VAR status: ost$status);


    VAR
      last_descriptor: ^oct$symbol_table_descriptor;


    last_descriptor := symbol_table_list;

    WHILE last_descriptor^.link <> NIL DO
      last_descriptor := last_descriptor^.link;
    WHILEND;

    NEXT last_descriptor^.link IN ocv$vel_scratch_seq;
    last_descriptor := last_descriptor^.link;
    IF last_descriptor = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_storage_allocation_failed, 'VLU6', status);
      RETURN;
    IFEND;

    last_descriptor^ := std^;
    last_descriptor^.link := NIL;


  PROCEND ocp$add_to_symbol_table_list;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_output_debug_table', EJECT ??

  PROCEDURE [XDCL] ocp$open_output_debug_table
    (    name: fst$file_reference;
     VAR file_identifier: amt$file_identifier;
     VAR segment: amt$segment_pointer;
     VAR debug_table_header: ^pmt$linker_debug_table_header;
     VAR status: ost$status);


    VAR
      attachment_options: ^fst$attachment_options,
      creation_validation_attributes: ^fst$file_cycle_attributes,
      ignore_status: ost$status;

    status.normal := TRUE;

    PUSH attachment_options: [1 .. 1];
    PUSH creation_validation_attributes: [1 .. 1];

    attachment_options^ [1].selector := fsc$access_and_share_modes;
    attachment_options^ [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options^ [1].access_modes.value := $fst$file_access_options
          [fsc$read, fsc$append, fsc$modify, fsc$shorten];
    attachment_options^ [1].share_modes.selector := fsc$determine_from_access_modes;

    creation_validation_attributes^ [1].selector := fsc$file_contents_and_processor;
    creation_validation_attributes^ [1].file_contents := fsc$data;
    creation_validation_attributes^ [1].file_processor := fsc$unknown_processor;

    fsp$open_file (name, amc$segment, attachment_options, {default_creation_attributes} NIL,
          creation_validation_attributes, creation_validation_attributes, {attribute_override} NIL,
          file_identifier, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (file_identifier, amc$sequence_pointer, segment, status);
    IF NOT status.normal THEN
      fsp$close_file (file_identifier, ignore_status);
      RETURN;
    IFEND;

    RESET segment.sequence_pointer;

    NEXT debug_table_header IN segment.sequence_pointer;
    IF debug_table_header = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, name, status);
      RETURN;
    IFEND;


  PROCEND ocp$open_output_debug_table;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL] ocp$open_input_debug_table', EJECT ??

  PROCEDURE [XDCL] ocp$open_input_debug_table
    (    debug_table: fst$file_reference;
     VAR file_identifier: amt$file_identifier;
     VAR segment: amt$segment_pointer;
     VAR debug_table_header: ^pmt$linker_debug_table_header;
     VAR status: ost$status);


    VAR
      attachment_options: ^fst$attachment_options,
      ignore_status: ost$status;

    status.normal := TRUE;

    PUSH attachment_options: [1 .. 1];

    attachment_options^ [1].selector := fsc$access_and_share_modes;
    attachment_options^ [1].access_modes.selector := fsc$specific_access_modes;
    attachment_options^ [1].access_modes.value := $fst$file_access_options [fsc$read];
    attachment_options^ [1].share_modes.selector := fsc$determine_from_access_modes;

    fsp$open_file (debug_table, amc$segment, attachment_options, {default_creation_attributes} NIL,
          {mandated_creation_attributes} NIL, {attribute_validation} NIL, {attribute_override} NIL,
          file_identifier, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    amp$get_segment_pointer (file_identifier, amc$sequence_pointer, segment, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;

    RESET segment.sequence_pointer;

    NEXT debug_table_header IN segment.sequence_pointer;
    IF debug_table_header = NIL THEN
      osp$set_status_abnormal ('OC', oce$e_premature_eof_on_file, debug_table, status);
      fsp$close_file (file_identifier, ignore_status);
      RETURN;
    IFEND;

    IF debug_table_header^.version <> pmc$linker_debug_table_version THEN
      osp$set_status_abnormal ('OC', oce$e_invalid_debug_tbl_version, debug_table, status);
      fsp$close_file (file_identifier, ignore_status);
      RETURN;
    IFEND;


  PROCEND ocp$open_input_debug_table;
?? OLDTITLE ??
MODEND ocm$ve_linker_utilities;
