?? RIGHT := 110 ??
MODULE ocm$process_info_element;
*copyc osd$default_pragmats
?? PUSH (LISTEXT := ON) ??
*copyc llt$information_element
*copyc llt$section_address
*copyc llt$identification
*copyc llt$library_member_header
*copyc llt$load_module_header
*copyc llt$module_dictionary
*copyc llt$object_library_header
*copyc llt$relocation
*copyc osp$set_status_abnormal
*copyc ost$status
*copyc pmt$program_name
*copyc occ$generate_predictor
*copyc oct$single_module_predictor_hdr
*copyc oct$offset_change_list
*copyc oct$predictor_header
*copyc oct$module_predictor_size
*copyc oct$section_directory
*copyc oce$metapatch_generator_errors
*copyc oct$code_section_directory
*copyc ocp$build_section_directory
*copyc ocp$new_global_offset
*copyc ocp$process_bti_records
*copyc ocp$process_rel_records
*copyc ocp$process_section_maps
*copyc ocp$convert_information_element
?? POP ??

*copyc och$process_info_element

  PROCEDURE [XDCL] ocp$process_info_element (p_predictor: ^SEQ ( * );
        p_int_ol: ^SEQ ( * );
        code_section_directory: ^oct$code_section_directory;
        module_code_sections: ^oct$module_code_sections;
    VAR status: ost$status);

    VAR
      aliases: record
        case boolean of
        = TRUE =
          pointer: ^pmt$module_list,
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      bti_records: record
        case boolean of
        = TRUE =
          pointer: ^llt$binding_section_template,
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      component: record
        case boolean of
        = TRUE =
          pointer: ^llt$component_information,
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      member: record
        case boolean of
        = TRUE =
          pointer: ^SEQ ( * ),
        = FALSE =
          pva: ^cell,
        casend,
      recend,


      relocation: record
        case boolean of
        = TRUE =
          pointer: ^llt$relocation,
        = FALSE =
          pva: ^cell,
        casend,
      recend,


      section_maps: record
        case boolean of
        = TRUE =
          pointer: ^llt$section_maps,
        = FALSE =
          pva: ^cell,
        casend,
      recend,

      counter: llt$module_index,
      current_module_name: pmt$program_name,
      current_module_used: boolean,
      found: boolean,
      i: llt$module_index,
      id_record: ^llt$identification,
      idr: ^llt$object_text_descriptor,
      info_element: ^llt$info_element_header,
      info_element_v_1_0: ^llt$info_element_header_1_0,
      information_element: llt$info_element_header,
      int_ol: ^SEQ ( * ),
      load_module_found: boolean,
      mod_dictionary_ocv: ^oct$offset_change_list,
      module_dictionary: ^llt$module_dictionary,
      module_header: ^llt$load_module_header,
      module_predictor: ^oct$module_predictor,
      module_predictor_header: ^oct$single_module_predictor_hdr,
      module_predictor_size: ^oct$module_predictor_size,
      new_header: ^llt$library_member_header,
      new_info_element: ^llt$info_element_header,
      new_offset: llt$section_address_range,
      new_pva: ^llt$object_text_descriptor,
      ol_dictionaries: ^llt$object_library_dictionaries,
      ol_header: ^llt$object_library_header,
      predictor: ^SEQ ( * ),
      predictor_header: ^oct$predictor_header,
      program_header: ^llt$library_member_header,
      pva: ^cell,
      save_ptr: ^cell,
      scl_header: ^llt$library_member_header,
      section_directory: ^oct$section_directory;

    int_ol := p_int_ol;
    predictor := p_predictor;

    RESET predictor;
    NEXT predictor_header IN predictor;
    IF predictor_header^.number_of_mod_ocv_elements > 0 THEN
      mod_dictionary_ocv := #PTR (predictor_header^.mod_dictionary_ocv, predictor^);
    ELSE
      mod_dictionary_ocv := NIL;
    IFEND;
    current_module_name := osc$null_name;
    current_module_used := TRUE;
    counter := 0;
    RESET int_ol;
    NEXT ol_header IN int_ol;
    NEXT ol_dictionaries: [1 .. ol_header^.number_of_dictionaries] IN int_ol;
    found := FALSE;
    i := 1;
    WHILE NOT found AND (i <= ol_header^.number_of_dictionaries) DO
      IF ol_dictionaries^ [i].kind = llc$module_dictionary THEN
        found := TRUE;
      ELSE
        i := i + 1;
      IFEND;
    WHILEND;
    IF NOT found THEN
      RETURN;
    IFEND;

    module_dictionary := #PTR (ol_dictionaries^ [i].module_dictionary, int_ol^);
    FOR i := 1 TO UPPERBOUND (module_dictionary^) DO
      IF current_module_used AND (counter < predictor_header^.number_module_predictors) THEN
        REPEAT
          NEXT module_predictor_header IN predictor;
          RESET predictor TO module_predictor_header;
          NEXT module_predictor: [[REP module_predictor_header^.predictor_size OF cell]] IN predictor;
          IF module_predictor_header^.kind = llc$load_module THEN
            load_module_found := TRUE;
          ELSE
            load_module_found := FALSE;
          IFEND;
          current_module_name := module_predictor_header^.module_name;
          counter := counter + 1;
          current_module_used := FALSE;
        UNTIL load_module_found OR (counter >= predictor_header^.number_module_predictors);
      IFEND;
      IF load_module_found THEN
        IF module_dictionary^ [i].kind = llc$load_module THEN
          module_header := #PTR (module_dictionary^ [i].module_header, int_ol^);

          IF (llc$information_element IN module_header^.elements_defined) THEN

            info_element := #PTR (module_header^.information_element, int_ol^);
            IF info_element^.version = llc$info_element_version THEN
              information_element := info_element^;
            ELSE
              ocp$convert_information_element (info_element, information_element);
            IFEND;

            IF module_dictionary^ [i].name = current_module_name THEN
              IF llc$interpretive_element IN module_header^.elements_defined THEN
                idr := #PTR (module_header^.interpretive_element, int_ol^);
                RESET int_ol TO idr;
                NEXT idr IN int_ol;
                NEXT id_record IN int_ol;
                ALLOCATE section_directory: [0 .. id_record^.greatest_section_ordinal];
                ocp$build_section_directory (module_predictor, module_header, int_ol, section_directory);
                IF information_element.number_of_rel_items > 0 THEN
                  relocation.pointer := #PTR (information_element.relocation_ptr, int_ol^);
                  ocp$process_rel_records (section_directory, relocation.pointer, information_element.
                        number_of_rel_items, code_section_directory^ [i], module_code_sections, status);
                  IF NOT status.normal THEN
                    RETURN;
                  IFEND;
                IFEND;
                IF information_element.number_of_template_items > 0 THEN
                  bti_records.pointer := #PTR (information_element.binding_template_ptr, int_ol^);
                  ocp$process_bti_records (module_predictor, module_predictor_header, section_directory,
                        bti_records.pointer, information_element.number_of_template_items);
                IFEND;
                IF information_element.number_of_section_maps > 0 THEN
                  section_maps.pointer := #PTR (information_element.section_maps, int_ol^);
                  ocp$process_section_maps (section_directory, mod_dictionary_ocv, section_maps.pointer,
                        information_element.number_of_section_maps, int_ol, module_predictor);
                IFEND;
                FREE section_directory;
              IFEND;
              current_module_used := TRUE;
            IFEND;
            IF info_element^.version = llc$info_element_version THEN
              IF info_element^.number_of_rel_items > 0 THEN
                relocation.pointer := #PTR (info_element^.relocation_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (relocation.pointer), mod_dictionary_ocv);
                relocation.pva := #address (#ring (relocation.pointer), #segment (relocation.pointer),
                      new_offset);
                info_element^.relocation_ptr := #REL (relocation.pointer, int_ol^);
              IFEND;
              IF info_element^.number_of_components > 0 THEN
                component.pointer := #PTR (info_element^.component_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (component.pointer), mod_dictionary_ocv);
                component.pva := #address (#ring (component.pointer), #segment (component.pointer),
                      new_offset);
                info_element^.component_ptr := #REL (component.pointer, int_ol^);
              IFEND;
              IF info_element^.number_of_template_items > 0 THEN
                bti_records.pointer := #PTR (info_element^.binding_template_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (bti_records.pointer), mod_dictionary_ocv);
                bti_records.pva := #address (#ring (bti_records.pointer), #segment (bti_records.pointer),
                      new_offset);
                info_element^.binding_template_ptr := #REL (bti_records.pointer, int_ol^);
              IFEND;
              IF info_element^.number_of_section_maps > 0 THEN
                section_maps.pointer := #PTR (info_element^.section_maps, int_ol^);
                new_offset := ocp$new_global_offset (#offset (section_maps.pointer), mod_dictionary_ocv);
                section_maps.pva := #address (#ring (section_maps.pointer), #segment (section_maps.pointer),
                      new_offset);
                info_element^.section_maps := #REL (section_maps.pointer, int_ol^);
              IFEND;
            ELSE
              info_element_v_1_0 := #PTR (module_header^.information_element, int_ol^);

              IF info_element_v_1_0^.number_of_rel_items > 0 THEN
                relocation.pointer := #PTR (info_element_v_1_0^.relocation_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (relocation.pointer), mod_dictionary_ocv);
                relocation.pva := #address (#ring (relocation.pointer), #segment (relocation.pointer),
                      new_offset);
                info_element_v_1_0^.relocation_ptr := #REL (relocation.pointer, int_ol^);
              IFEND;
              IF info_element_v_1_0^.number_of_components > 0 THEN
                component.pointer := #PTR (info_element_v_1_0^.component_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (component.pointer), mod_dictionary_ocv);
                component.pva := #address (#ring (component.pointer), #segment (component.pointer),
                      new_offset);
                info_element_v_1_0^.component_ptr := #REL (component.pointer, int_ol^);
              IFEND;
              IF info_element_v_1_0^.number_of_template_items > 0 THEN
                bti_records.pointer := #PTR (info_element_v_1_0^.binding_template_ptr, int_ol^);
                new_offset := ocp$new_global_offset (#offset (bti_records.pointer), mod_dictionary_ocv);
                bti_records.pva := #address (#ring (bti_records.pointer), #segment (bti_records.pointer),
                      new_offset);
                info_element_v_1_0^.binding_template_ptr := #REL (bti_records.pointer, int_ol^);
              IFEND;
              IF info_element_v_1_0^.number_of_section_maps > 0 THEN
                section_maps.pointer := #PTR (info_element_v_1_0^.section_maps, int_ol^);
                new_offset := ocp$new_global_offset (#offset (section_maps.pointer), mod_dictionary_ocv);
                section_maps.pva := #address (#ring (section_maps.pointer), #segment (section_maps.pointer),
                      new_offset);
                info_element_v_1_0^.section_maps := #REL (section_maps.pointer, int_ol^);
              IFEND;
            IFEND;
          IFEND;

          IF mod_dictionary_ocv <> NIL THEN
            IF (llc$interpretive_element IN module_header^.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_element, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_element := #REL (new_pva, int_ol^);
            IFEND;
            IF (llc$information_element IN module_header^.elements_defined) THEN
              pva := #PTR (module_header^.information_element, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_info_element := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.information_element := #REL (new_info_element, int_ol^);
            IFEND;
            IF (llc$library_element IN module_header^.interpretive_header.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_header.library_list, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_header.library_list := #REL (new_pva, int_ol^);
            IFEND;
            IF (llc$section_element IN module_header^.interpretive_header.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_header.section_definitions, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_header.section_definitions := #REL (new_pva, int_ol^);
            IFEND;
            IF (llc$entry_point_element IN module_header^.interpretive_header.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_header.entry_points, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_header.entry_points := #REL (new_pva, int_ol^);
            IFEND;
            IF (llc$external_element IN module_header^.interpretive_header.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_header.external_linkages, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_header.external_linkages := #REL (new_pva, int_ol^);
            IFEND;
            IF (llc$transfer_symbol_element IN module_header^.interpretive_header.elements_defined) THEN
              pva := #PTR (module_header^.interpretive_header.transfer_symbol, int_ol^);
              new_offset := ocp$new_global_offset (#offset (pva), mod_dictionary_ocv);
              new_pva := #address (#ring (pva), #segment (pva), new_offset);
              module_header^.interpretive_header.transfer_symbol := #REL (new_pva, int_ol^);
            IFEND;
          IFEND;
        IFEND;
      IFEND;
    FOREND;
  PROCEND ocp$process_info_element;
MODEND ocm$process_info_element;
