☕ Um Café no Bellacosa Mainframe
Gostou do conteúdo? Ajude a manter o café quente, o COBOL compilando e o mainframe acordado. 😄
☕ Pague um café ao Bellacosa

Translate

Mostrar mensagens com a etiqueta Binder. Mostrar todas as mensagens
Mostrar mensagens com a etiqueta Binder. Mostrar todas as mensagens

quinta-feira, 21 de julho de 2022

🚨 Alerta Vermelho na Enterprise: Descobrimos Que Não Era o COBOL 5... Era o 6.4!

Bellacosa Mainframe e atencao ao compilar uma nova função intrinseca


🚨 Alerta Vermelho na Enterprise: Descobrimos Que Não Era o COBOL 5... Era o 6.4!

Adendo — Em qual versão do Enterprise COBOL as funções definidas pelo usuário estão disponíveis?

Antes de avançarmos para a sala de máquinas, precisamos corrigir uma informação importante do artigo original:

As User-Defined Functions com FUNCTION-ID não foram introduzidas no Enterprise COBOL 5. Elas chegaram oficialmente ao IBM Enterprise COBOL for z/OS 6.4.

O suporte faz parte da implementação IBM de recursos definidos pelo padrão COBOL 2002. No Enterprise COBOL 6.4, o programador passou a poder criar funções próprias, declarar parâmetros, retornar um valor e invocá-las por meio de um identificador de função. (IBM)

🖖 Adendo do Capitão Kirk

Enterprise COBOL 6.4, compilação e JCL para User-Defined Functions

Intrínseca ou definida pelo usuário?

Existe uma diferença importante de terminologia.

Uma função como:

FUNCTION CURRENT-DATE
FUNCTION LENGTH
FUNCTION UPPER-CASE
FUNCTION NUMVAL

é uma função intrínseca, pois já vem implementada no compilador COBOL.

Uma função criada com:

FUNCTION-ID. CALCULA-DESCONTO.

é uma User-Defined Function, ou função definida pelo usuário.

Ela pode ser usada de maneira parecida com uma função intrínseca, mas não passa a fazer parte do compilador. Ela continua sendo um componente da aplicação que precisa ser compilado e disponibilizado corretamente.

Portanto, tecnicamente, não estamos adicionando uma nova função intrínseca ao compilador IBM. Estamos criando uma função de aplicação que pode ser invocada com uma sintaxe semelhante.


A partir de qual versão está disponível?

No ambiente IBM Z, o suporte a User-Defined Functions foi introduzido no:

IBM Enterprise COBOL for z/OS 6.4

O recurso utiliza o parágrafo:

FUNCTION-ID

e o delimitador:

END FUNCTION

A função também deve possuir obrigatoriamente uma cláusula RETURNING no cabeçalho da PROCEDURE DIVISION. (IBM)

Resumo de compatibilidade

Versão do Enterprise COBOLUser-Defined Function com FUNCTION-ID
Enterprise COBOL 4.xNão
Enterprise COBOL 5.1Não
Enterprise COBOL 5.2Não
Enterprise COBOL 6.1Não
Enterprise COBOL 6.2Não
Enterprise COBOL 6.3Não
Enterprise COBOL 6.4Sim

Em alguns ambientes, o Enterprise COBOL 6.4 pode precisar estar com os PTFs recomendados pela IBM instalados para que correções e recursos complementares, como protótipos de função, estejam disponíveis.

O suporte básico a User-Defined Functions pertence ao 6.4. Já o suporte ampliado a function prototypes, relacionado ao padrão COBOL 2014, foi fornecido por manutenção do compilador 6.4, incluindo o APAR/PTF associado ao suporte documentado pela IBM.


Programa completo para treinamento

Neste exemplo, criaremos a função:

CALCULA-IMPOSTO

Ela receberá:

  • valor da operação;

  • alíquota percentual;

E retornará:

  • valor do imposto.

A função e o programa principal serão colocados no mesmo membro-fonte para facilitar o laboratório.


Fonte COBOL completo

       IDENTIFICATION DIVISION.
       FUNCTION-ID. CALCULA-IMPOSTO.

       DATA DIVISION.
       LINKAGE SECTION.

       01  LK-VALOR             PIC S9(09)V99 COMP-3.
       01  LK-ALIQUOTA          PIC S9(03)V99 COMP-3.
       01  LK-IMPOSTO           PIC S9(09)V99 COMP-3.

       PROCEDURE DIVISION
           USING BY REFERENCE LK-VALOR
                              LK-ALIQUOTA
           RETURNING LK-IMPOSTO.

           COMPUTE LK-IMPOSTO ROUNDED =
               LK-VALOR * LK-ALIQUOTA / 100

           GOBACK.

       END FUNCTION CALCULA-IMPOSTO.


       IDENTIFICATION DIVISION.
       PROGRAM-ID. MAINPROG.

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.

       REPOSITORY.
           FUNCTION CALCULA-IMPOSTO.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  WS-VALOR             PIC S9(09)V99 COMP-3
                                VALUE 1000.
       01  WS-ALIQUOTA          PIC S9(03)V99 COMP-3
                                VALUE 18.50.
       01  WS-IMPOSTO           PIC S9(09)V99 COMP-3.

       01  WS-VALOR-EDITADO     PIC ZZZ,ZZZ,ZZ9.99-.
       01  WS-ALIQ-EDITADA      PIC ZZ9.99-.
       01  WS-IMPOSTO-EDITADO   PIC ZZZ,ZZZ,ZZ9.99-.

       PROCEDURE DIVISION.

           DISPLAY "========================================"
           DISPLAY " BELLACOSA MAINFRAME - TESTE DE FUNCAO"
           DISPLAY "========================================"

           COMPUTE WS-IMPOSTO =
               CALCULA-IMPOSTO(
                   WS-VALOR
                   WS-ALIQUOTA
               )

           MOVE WS-VALOR    TO WS-VALOR-EDITADO
           MOVE WS-ALIQUOTA TO WS-ALIQ-EDITADA
           MOVE WS-IMPOSTO  TO WS-IMPOSTO-EDITADO

           DISPLAY "VALOR DA OPERACAO : " WS-VALOR-EDITADO
           DISPLAY "ALIQUOTA           : " WS-ALIQ-EDITADA "%"
           DISPLAY "IMPOSTO CALCULADO  : " WS-IMPOSTO-EDITADO

           IF WS-IMPOSTO = 185
               DISPLAY "RESULTADO CORRETO. MISSAO CUMPRIDA."
           ELSE
               DISPLAY "RESULTADO INESPERADO. CHAME O SPOCK."
           END-IF

           GOBACK.

       END PROGRAM MAINPROG.

Por que a função aparece antes do programa?

Quando a função e o programa chamador são compilados no mesmo grupo de compilação, sem o uso de um protótipo separado, a definição da função deve aparecer antes da unidade que a utiliza.

A IBM recomenda, para projetos maiores, que a função seja mantida em arquivo separado e que um protótipo seja usado no programa chamador. Entretanto, para treinamento, colocar a função e o programa no mesmo membro é uma maneira direta de compreender o mecanismo. (IBM)

Há uma consequência importante:

A primeira unidade encontrada pelo compilador pode tornar-se o ponto de entrada padrão do módulo.

Como nossa primeira unidade é CALCULA-IMPOSTO, precisamos informar ao Binder que o verdadeiro programa inicial é:

MAINPROG

Por isso usaremos:

ENTRY MAINPROG

durante a linkedição.

Sem essa instrução, a nave pode tentar decolar pela porta da engenharia em vez de sair pela ponte de comando.


JCL completo: compilar, linkeditar e executar

O exemplo abaixo apresenta um fluxo tradicional com três etapas:

  1. COBOL — compilação;

  2. LKED — linkedição;

  3. RUN — execução.

Os nomes das bibliotecas precisam ser adaptados à instalação da sua empresa.

//BLCOBUDF JOB (ACCT),'COBOL UDF',
//             CLASS=A,
//             MSGCLASS=X,
//             MSGLEVEL=(1,1),
//             NOTIFY=&SYSUID
//*
//* ==========================================================
//* BELLACOSA MAINFRAME
//* COMPILACAO DE USER-DEFINED FUNCTION - COBOL 6.4
//* ==========================================================
//*
//COBOL    EXEC PGM=IGYCRCTL,
// PARM='LIB,OBJECT,RENT,APOST,LIST,MAP,XREF,OFFSET'
//STEPLIB  DD DISP=SHR,
//            DSN=IGY.V6R4M0.SIGYCOMP
//SYSIN    DD DISP=SHR,
//            DSN=SEU.USUARIO.COBOL(CALCUDF)
//SYSLIN   DD DSN=&&OBJETO,
//            DISP=(NEW,PASS),
//            UNIT=SYSDA,
//            SPACE=(TRK,(5,5)),
//            DCB=(RECFM=FB,LRECL=80,BLKSIZE=0)
//SYSPRINT DD SYSOUT=*
//SYSOUT   DD SYSOUT=*
//SYSUT1   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT2   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT3   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT4   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT5   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT6   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT7   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT8   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT9   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT10  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT11  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT12  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT13  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT14  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//SYSUT15  DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//*
//LKED     EXEC PGM=IEWL,
// PARM='LIST,MAP,XREF,LET,RENT'
//SYSLIB   DD DISP=SHR,
//            DSN=CEE.SCEELKED
//         DD DISP=SHR,
//            DSN=CEE.SCEELKEX
//SYSLMOD  DD DISP=SHR,
//            DSN=SEU.USUARIO.LOAD(MAINPROG)
//SYSLIN   DD DISP=(OLD,DELETE),
//            DSN=&&OBJETO
//         DD *
  ENTRY MAINPROG
  NAME MAINPROG(R)
/*
//SYSPRINT DD SYSOUT=*
//SYSUT1   DD UNIT=SYSDA,SPACE=(CYL,(1,1))
//*
//RUN      EXEC PGM=MAINPROG,
//            COND=(0,NE)
//STEPLIB  DD DISP=SHR,
//            DSN=SEU.USUARIO.LOAD
//         DD DISP=SHR,
//            DSN=CEE.SCEERUN
//         DD DISP=SHR,
//            DSN=CEE.SCEERUN2
//SYSOUT   DD SYSOUT=*
//CEEDUMP  DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*
//

Bibliotecas que devem ser adaptadas

Biblioteca do compilador

No exemplo:

DSN=IGY.V6R4M0.SIGYCOMP

Esse nome varia de instalação para instalação.

Você poderá encontrar algo parecido com:

IGY.V6R4M0.SIGYCOMP
IGY640.SIGYCOMP
SYS1.IGY640.SIGYCOMP
CBC.SIGYCOMP

Não copie cegamente o nome do exemplo.

Pergunte ao sysprog, consulte um JCL COBOL já utilizado na empresa ou verifique a PROC oficial de compilação.


Biblioteca de runtime do Language Environment

Normalmente são utilizadas:

CEE.SCEERUN
CEE.SCEERUN2

Para a linkedição, podem aparecer:

CEE.SCEELKED
CEE.SCEELKEX

Os nomes e concatenações dependem da configuração do z/OS e do Language Environment.


Biblioteca de load modules

No exemplo:

DSN=SEU.USUARIO.LOAD

Ela precisa existir como uma PDS ou PDSE adequada para módulos executáveis.

Uma definição típica poderia ser criada por meio do ISPF 3.2 ou por JCL, usando atributos compatíveis com a instalação.

Em ambientes modernos, normalmente é preferível utilizar uma PDSE para a biblioteca de carga.


Versão mais curta usando uma PROC catalogada

Muitos ambientes IBM Z possuem procedures catalogadas como:

IGYWCL
IGYWCLG
IGYWC

Os nomes representam, em geral:

  • C: compile;

  • L: link-edit;

  • G: go ou execute.

Um exemplo conceitual seria:

//BLCOBUDF JOB (ACCT),'COBOL UDF',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//COBCLG   EXEC IGYWCLG,
//         PARM.COBOL='LIB,RENT,APOST,LIST,MAP,XREF'
//COBOL.SYSIN DD DISP=SHR,
//         DSN=SEU.USUARIO.COBOL(CALCUDF)
//LKED.SYSLMOD DD DISP=SHR,
//         DSN=SEU.USUARIO.LOAD(MAINPROG)
//LKED.SYSIN DD *
  ENTRY MAINPROG
  NAME MAINPROG(R)
/*
//GO.STEPLIB DD DISP=SHR,
//         DSN=SEU.USUARIO.LOAD
//GO.SYSOUT DD SYSOUT=*
//GO.CEEDUMP DD SYSOUT=*

Entretanto, há um alerta vermelho piscando na ponte:

As procedures catalogadas não são idênticas em todas as empresas.

A PROC pode:

  • possuir outro nome;

  • utilizar outros qualificadores;

  • não aceitar os mesmos overrides;

  • já incluir bibliotecas adicionais;

  • ter parâmetros obrigatórios;

  • possuir nomes internos diferentes para as etapas.

Antes de utilizá-la, execute no ISPF:

TSO ISRDDN

ou consulte os JCLs-padrão da instalação.

Também é possível procurar a PROC nas bibliotecas de procedures, normalmente concatenadas em JES2 PROCLIB.


Entendendo o REPOSITORY

O programa chamador possui:

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.

       REPOSITORY.
           FUNCTION CALCULA-IMPOSTO.

Isso informa ao compilador que CALCULA-IMPOSTO é uma função conhecida pelo programa.

Com essa declaração, podemos escrever:

COMPUTE WS-IMPOSTO =
    CALCULA-IMPOSTO(WS-VALOR WS-ALIQUOTA)

A IBM documenta que a declaração no REPOSITORY permite invocar a função sem repetir a palavra reservada FUNCTION. (IBM)

Dependendo da forma de declaração e do contexto, uma referência explícita também pode assumir a forma:

FUNCTION CALCULA-IMPOSTO(
    WS-VALOR
    WS-ALIQUOTA
)

No exemplo apresentado, utilizamos o REPOSITORY para deixar a expressão mais limpa.


Saída esperada no SYSOUT

O resultado deverá ser semelhante a:

========================================
 BELLACOSA MAINFRAME - TESTE DE FUNCAO
========================================
VALOR DA OPERACAO :       1,000.00
ALIQUOTA           :          18.50%
IMPOSTO CALCULADO  :         185.00
RESULTADO CORRETO. MISSAO CUMPRIDA.

Return codes esperados

Em uma missão bem-sucedida, procure:

COBOL RC=0000
LKED  RC=0000
RUN   RC=0000

Dependendo das opções e dos avisos encontrados, a compilação pode terminar com:

RC=0004

Isso significa que houve advertências, não necessariamente um erro fatal. Mesmo assim, analise todas as mensagens.

Interpretação tradicional

Return codeSignificado geral
0000Processamento concluído sem diagnóstico relevante
0004Advertências
0008Erros que normalmente impedem o uso seguro
0012Erros graves
0016Erro muito grave ou falha de processamento

A interpretação exata deve considerar as mensagens emitidas pelo compilador e pelo Binder.


Erro: FUNCTION-ID não reconhecido

Caso o compilador apresente mensagens indicando que:

FUNCTION-ID

não é reconhecido, as causas mais prováveis são:

  1. O JCL está chamando um compilador anterior ao Enterprise COBOL 6.4.

  2. A STEPLIB aponta para outra versão do compilador.

  3. A PROC catalogada ainda referencia COBOL 6.2 ou 6.3.

  4. O produto 6.4 está instalado, mas não é a versão selecionada pelo JCL.

  5. O fonte está sendo processado por uma ferramenta intermediária incompatível.

  6. O editor ou analisador local conhece uma gramática COBOL antiga.

Verifique no listing de compilação a identificação da versão.

Você deverá encontrar uma indicação semelhante a:

IBM Enterprise COBOL for z/OS 6.4

Não confie apenas no nome da PROC.

Uma PROC chamada COBOL64 pode ter sido alterada, enquanto uma PROC chamada apenas COBOL pode estar usando o compilador mais recente.

Como Spock diria:

“O nome de um membro não constitui evidência lógica do conteúdo de sua STEPLIB.”


Erro de linkedição: ponto de entrada incorreto

Como a função aparece primeiro no grupo de compilação, o Binder pode selecionar a entrada errada caso não seja informado explicitamente.

Por isso usamos:

ENTRY MAINPROG

Para compilações AMODE 31 com LP(32), a IBM orienta que seja fornecida uma instrução ENTRY para o programa principal quando uma compilação contém funções e programas e a função aparece antes do programa. (IBM)

Se o ENTRY estiver ausente ou incorreto, poderão ocorrer:

  • início da execução no componente errado;

  • erro de entrada não encontrada;

  • comportamento imprevisível;

  • falha de linkedição;

  • abend durante a inicialização.


Não use CALL para invocar a função

Uma User-Defined Function deve ser utilizada como função:

COMPUTE WS-IMPOSTO =
    CALCULA-IMPOSTO(WS-VALOR WS-ALIQUOTA)

Não faça:

CALL "CALCULA-IMPOSTO"

A documentação IBM alerta que invocar uma User-Defined Function por meio da instrução CALL produz comportamento imprevisível. (IBM)

Se o componente foi projetado para ser chamado com CALL, escreva-o como subprograma com:

PROGRAM-ID

Se foi projetado como função, escreva-o com:

FUNCTION-ID

Não misture as duas interfaces.


ENTRY-INTERFACE

O FUNCTION-ID também pode controlar a forma de geração e invocação por meio de ENTRY-INTERFACE.

As User-Defined Functions podem ser estruturadas para diferentes formas de ligação, incluindo:

  • estática;

  • dinâmica;

  • DLL.

O padrão documentado para ENTRY-INTERFACE é STATIC. (IBM)

Para o primeiro laboratório, mantenha a configuração padrão.

A invocação estática reduz a quantidade de peças móveis e facilita:

  • compilação;

  • linkedição;

  • testes;

  • diagnóstico;

  • implantação inicial.

Só avance para modelos dinâmicos depois de dominar:

  • protótipos;

  • external names;

  • binder;

  • load libraries;

  • Language Environment;

  • convenções de interface.


Cuidado com BY REFERENCE

No exemplo, os parâmetros são recebidos com:

USING BY REFERENCE

Isso significa que a função recebe referências aos itens do programa chamador.

Embora uma boa função de cálculo não deva modificar seus argumentos, o uso de referência exige disciplina.

Evite comandos como:

MOVE ZERO TO LK-VALOR

Isso poderia alterar dados pertencentes ao chamador, dependendo da interface e do argumento utilizado.

Para obter um comportamento semelhante ao BY CONTENT, o Enterprise COBOL 6.4 disponibiliza a função CONTENT-OF. Nesse modelo, a definição formal continua usando BY REFERENCE, mas o argumento é protegido por uma cópia temporária criada na invocação. (IBM)

Exemplo conceitual:

REPOSITORY.
    FUNCTION CONTENT-OF INTRINSIC
    FUNCTION CALCULA-IMPOSTO.

Invocação:

COMPUTE WS-IMPOSTO =
    CALCULA-IMPOSTO(
        CONTENT-OF(WS-VALOR)
        CONTENT-OF(WS-ALIQUOTA)
    )

Isso é especialmente útil quando você deseja deixar claro que a função não deve alterar os argumentos fornecidos.


Dicas de compilação do Scotty

1. Comece sem otimização agressiva

Durante os primeiros testes, prefira opções que facilitem diagnóstico.

Por exemplo:

LIST,MAP,XREF,OFFSET

Depois que o programa estiver estabilizado, avalie as opções de otimização adotadas pela instalação.


2. Use TEST em ambiente de desenvolvimento

Caso a empresa utilize IBM Debug for z/OS, as opções apropriadas de depuração podem ajudar a acompanhar:

  • entrada na função;

  • conteúdo dos parâmetros;

  • valor retornado;

  • fluxo de execução.

As opções exatas dependem das ferramentas e padrões locais.


3. Verifique o listing

No listing de compilação, confirme:

  • versão do compilador;

  • opções efetivamente utilizadas;

  • definição da função;

  • referências à função;

  • mensagens de severidade;

  • offsets;

  • informações do objeto gerado.


4. Não esconda erros com COND inadequado

No laboratório, a execução deve ocorrer apenas quando as etapas anteriores forem bem-sucedidas.

Uma alternativa moderna é usar:

//RUN EXEC PGM=MAINPROG,
// IF (COBOL.RC LE 4 AND LKED.RC LE 4) THEN

ou estruturas IF/THEN/ELSE/ENDIF do JCL, conforme o padrão da empresa.

Evite executar um módulo quando a compilação terminou com erro grave.


5. Teste limites numéricos

Não teste apenas:

1000 × 18,5%

Teste também:

  • valor zero;

  • alíquota zero;

  • valor negativo, se permitido;

  • alíquota com muitas casas;

  • valor máximo do PIC;

  • resultado próximo de overflow;

  • arredondamento;

  • sinal;

  • casas decimais;

  • truncamento.


Checklist de lançamento da função

Antes de Kirk autorizar a partida, confirme:

[ ] Enterprise COBOL 6.4 está realmente sendo utilizado
[ ] FUNCTION-ID foi reconhecido
[ ] A função possui RETURNING
[ ] A função termina com END FUNCTION
[ ] O programa termina com END PROGRAM
[ ] A função aparece antes do chamador no mesmo grupo
[ ] O REPOSITORY declara a função
[ ] ENTRY MAINPROG foi fornecido ao Binder
[ ] A load library existe
[ ] CEE.SCEERUN está disponível na execução
[ ] Os parâmetros possuem formatos compatíveis
[ ] O valor de retorno cabe no campo receptor
[ ] Não existe CALL para a User-Defined Function
[ ] O listing foi revisado
[ ] Os testes de limite foram executados

Diário de bordo do Capitão Kirk

Criar uma função definida pelo usuário no Enterprise COBOL 6.4 não é apenas aprender uma nova sintaxe.

É aprender que o COBOL também evolui.

A linguagem que processava cartões perfurados agora pode organizar regras em funções reutilizáveis, oferecer interfaces mais expressivas e aproximar sistemas críticos de práticas modernas de engenharia de software.

Mas o Padawan precisa compreender toda a cadeia:

FONTE
  ↓
COMPILADOR COBOL 6.4
  ↓
OBJETO
  ↓
BINDER
  ↓
LOAD MODULE
  ↓
LANGUAGE ENVIRONMENT
  ↓
EXECUÇÃO

A função não “se instala” como um plugin.

Ela é:

  1. escrita;

  2. compilada;

  3. linkedita;

  4. armazenada em uma load library;

  5. disponibilizada ao programa que a utilizará.

Na ponte da Enterprise, Kirk conclui:

“Não basta descobrir um novo recurso. É preciso saber como colocá-lo em produção sem explodir os motores.”

Spock examina o listing e responde:

“Compilação RC zero, linkedição RC zero e resultado igual a 185. A missão é logicamente satisfatória.”

E Scotty, olhando para o Binder, acrescenta:

“Desde que ninguém esqueça o ENTRY MAINPROG, capitão.”

Esse pequeno detalhe resume uma grande verdade do mundo mainframe:

O código pode estar perfeito, mas a missão só termina quando compilação, linkedição e execução trabalham como uma única tripulação.

 

terça-feira, 24 de maio de 2022

Da Compilação à Execução de um Programa COBOL

 

Bellacosa Mainframe e a compilaçao de um programa cobol

☕ Um Café no Bellacosa Mainframe

Da Compilação à Execução de um Programa COBOL

A jornada completa do código-fonte até a CPU do IBM Z

Para quem está começando no universo mainframe, compilar um programa COBOL pode parecer uma tarefa simples:

Escrever o código
Compilar
Executar

Mas, no IBM Z, existe uma verdadeira cadeia industrial entre a primeira linha do fonte e o momento em que uma CPU começa a executar as instruções do programa.

O código pode depender de copybooks, comandos CICS, instruções SQL, chamadas IMS, interfaces Adabas, arquivos QSAM, clusters VSAM, bibliotecas de carga, JCL, JES2, Language Environment, memória e vários componentes do z/OS.

Por isso, dizer que um programa foi apenas “compilado e executado” é como afirmar que um avião simplesmente saiu do papel e começou a voar.

Entre o projeto e o voo existem dezenas de etapas.

Esta série em quatro capítulos foi criada para mostrar essa jornada completa de maneira progressiva, sempre pensando no Programador COBOL Padawan que deseja compreender não apenas como escrever código, mas como o mainframe realmente pensa.


O grande mapa da jornada

Antes de conhecer cada capítulo, observe o fluxo completo:

Regra de negócio
       ↓
Código-fonte COBOL
       ↓
Copybooks
       ↓
Tradução CICS
       ↓
Processamento Db2
       ↓
Interfaces IMS e Adabas
       ↓
Compilação
       ↓
Código objeto
       ↓
Binder
       ↓
Load module
       ↓
Load library
       ↓
JCL ou transação
       ↓
JES2 ou subsistema online
       ↓
Loader
       ↓
Memória
       ↓
Dispatcher
       ↓
CPU
       ↓
Dados, relatórios e resultados

Cada etapa possui uma responsabilidade específica.

Quando uma delas falha, o problema pode aparecer como:

  • erro de compilação;

  • erro de linkedição;

  • package Db2 inválido;

  • programa não encontrado;

  • arquivo ausente;

  • FILE STATUS;

  • SQLCODE;

  • erro CICS;

  • status IMS;

  • response code Adabas;

  • return code;

  • abend.

A melhor forma de investigar qualquer problema é descobrir em qual parte dessa cadeia ele ocorreu.


Parte I — O nascimento do programa COBOL

Código-fonte, bibliotecas e copybooks

O primeiro capítulo apresenta o ponto de partida: o código-fonte COBOL.

É nele que o programador transforma uma regra de negócio em instruções como:

MOVE
COMPUTE
PERFORM
READ
WRITE
CALL

Porém, o programa raramente vive sozinho.

Muitas aplicações utilizam copybooks para compartilhar:

  • layouts de arquivos;

  • registros;

  • áreas de comunicação;

  • constantes;

  • códigos de retorno;

  • estruturas de mensagens;

  • campos de tabelas;

  • contratos entre programas.

Um programa pode conter:

       COPY CPYCLI01.

Durante o processo de compilação, o conteúdo desse copybook é incorporado logicamente ao fonte.

O capítulo também explica uma diferença fundamental:

COPY inclui fonte.
CALL executa outro programa.

Essa distinção é importante porque um copybook não é um módulo executável.

Ele é uma estrutura reutilizável inserida no programa durante sua preparação.

Outro ponto central é que o copybook funciona como um contrato.

Se dois programas compartilham uma área de memória, ambos precisam interpretar exatamente o mesmo layout.

Uma alteração feita sem análise de impacto pode provocar:

  • campos deslocados;

  • valores incorretos;

  • erros numéricos;

  • corrupção de dados;

  • abends;

  • falhas silenciosas.

A primeira parte também mostra como o compilador localiza copybooks por meio de bibliotecas associadas a DD statements como SYSLIB.

A ordem dessas bibliotecas pode determinar qual versão do copybook será utilizada.

Isso significa que até mesmo uma compilação com retorno zero pode gerar um programa incorreto caso tenha utilizado uma versão inadequada de determinada estrutura.

Leia a Parte I

https://eljefemidnightlunch.blogspot.com/2022/01/da-compilacao-execucao-de-um-programa.html


Parte II — CICS, Db2, IMS e Adabas

O que acontece antes da compilação

O segundo capítulo mostra que nem tudo o que aparece dentro de um programa COBOL pertence diretamente à linguagem.

Comandos como:

           EXEC CICS
                READ FILE('CLIENTES')
           END-EXEC.

ou:

           EXEC SQL
                SELECT NOME
                  INTO :WS-NOME
                  FROM CLIENTES
           END-EXEC.

precisam ser processados por componentes especializados.

CICS

Os comandos EXEC CICS são interpretados pelo tradutor CICS.

O fluxo conceitual é:

Fonte COBOL com EXEC CICS
             ↓
Tradutor CICS
             ↓
Fonte COBOL preparado
             ↓
Compilador

O programa pede ao CICS que execute serviços como:

  • leitura de arquivos;

  • envio e recebimento de mapas;

  • acesso a filas;

  • chamada de programas;

  • controle de transações;

  • sincronização;

  • gerenciamento de recursos.

O COBOL contém a regra de negócio.

O CICS administra o ambiente transacional.

Db2

Comandos EXEC SQL precisam ser processados pelo pré-compilador Db2 ou por um coprocessador integrado.

Esse processamento pode gerar:

Fonte COBOL preparado
DBRM

O fonte segue para o compilador.

O DBRM segue para o BIND do Db2.

Esse BIND cria um package com as instruções SQL preparadas.

O capítulo esclarece uma confusão frequente:

Binder do z/OS cria o executável.
BIND do Db2 cria o package SQL.

São processos diferentes.

IMS

Programas COBOL podem acessar bancos hierárquicos e mensagens IMS por meio de chamadas DL/I.

Entre as funções comuns estão:

GU
GN
GNP
ISRT
REPL
DLET

O ambiente também utiliza estruturas como:

  • DBD;

  • PSB;

  • PCB;

  • SSA;

  • layouts de segmentos.

Adabas

O acesso ao Adabas pode envolver:

  • control blocks;

  • format buffers;

  • record buffers;

  • search buffers;

  • value buffers;

  • interfaces de chamada;

  • response codes.

Apesar de suas diferenças, CICS, Db2, IMS e Adabas compartilham o mesmo princípio:

O programa COBOL executa a regra de negócio e solicita serviços a subsistemas especializados.

Leia a Parte II

https://eljefemidnightlunch.blogspot.com/2022/02/da-compilacao-execucao-de-um-programa.html


Parte III — Compilação, linkedição e load library

Como o fonte se transforma em executável

O terceiro capítulo entra no coração técnico da transformação.

Depois que o fonte foi preparado, o compilador COBOL entra em cena.

Seu trabalho não se limita a trocar comandos por instruções de máquina.

Ele também analisa:

  • sintaxe;

  • campos;

  • tipos de dados;

  • tamanhos;

  • parágrafos;

  • referências;

  • opções;

  • arquivos;

  • copybooks;

  • expressões;

  • compatibilidade;

  • oportunidades de otimização.

O resultado principal é o código objeto.

Fonte COBOL
      ↓
Compilador
      ↓
Código objeto

Porém, o código objeto ainda pode possuir referências não resolvidas.

Um programa pode chamar:

           CALL 'PGMVALID'
                USING AREA-DADOS.

Se essa chamada precisar ser resolvida antecipadamente, será necessário localizar o módulo correspondente durante a linkedição.

O Binder

O Binder do z/OS reúne:

  • código objeto;

  • rotinas;

  • interfaces;

  • módulos externos;

  • pontos de entrada;

  • componentes de runtime.

O resultado é o módulo executável.

Código objeto
      +
Dependências
      ↓
Binder
      ↓
Load module ou program object

Esse executável é gravado em uma biblioteca como:

EMPRESA.SISTEMA.LOADLIB(PGMCLI01)

Chamadas estáticas e dinâmicas

O capítulo também explica a diferença entre chamadas estáticas e dinâmicas.

Estática

A dependência é resolvida durante a linkedição.

Dinâmica

O módulo é procurado durante a execução.

Essa escolha afeta:

  • implantação;

  • tamanho do executável;

  • manutenção;

  • versionamento;

  • risco de programa não encontrado;

  • necessidade de relinkedição.

Return codes

Compilador e Binder produzem mensagens e return codes.

Um RC=0 indica que a etapa terminou normalmente, mas não prova que a lógica está correta.

Um RC=4 pode conter warnings importantes.

Um erro de linkedição pode indicar:

  • símbolo não resolvido;

  • módulo ausente;

  • biblioteca errada;

  • ponto de entrada incorreto;

  • interface incompatível.

O capítulo reforça uma lição essencial:

Programa compilado não significa programa testado.

Leia a Parte III

https://eljefemidnightlunch.blogspot.com/2022/03/da-compilacao-execucao-de-um-programa.html


Parte IV — Da load library à CPU

JCL, JES2, QSAM, VSAM, memória e processamento

O quarto capítulo acompanha o executável durante a execução real.

Depois da linkedição, o programa está pronto, mas ainda permanece parado em uma load library.

No ambiente batch, o JCL solicita sua execução:

//STEP01 EXEC PGM=PGMCLI01

Uma STEPLIB pode informar onde o módulo deve ser procurado:

//STEPLIB DD DISP=SHR,
//           DSN=EMPRESA.SISTEMA.LOADLIB

Se o módulo não for encontrado, pode ocorrer um erro como S806.

QSAM

Programas que acessam arquivos sequenciais podem utilizar QSAM.

No COBOL:

ASSIGN TO CLIENTES

No JCL:

//CLIENTES DD DISP=SHR,
//            DSN=EMPRESA.DADOS.CLIENTES

A ligação é:

Nome lógico COBOL
       ↓
DDNAME
       ↓
Dataset físico

VSAM

VSAM oferece organizações como:

  • KSDS;

  • ESDS;

  • RRDS;

  • LDS;

  • VRRDS.

Um KSDS pode ser acessado por chave e também de forma sequencial.

O programa precisa verificar o FILE STATUS depois das operações.

Retornos como 00, 10, 22, 23, 35 e 39 possuem significados diferentes conforme a operação e o contexto.

JES2

O JES2 administra o fluxo batch.

Ele:

  • recebe o job;

  • mantém filas;

  • utiliza o spool;

  • organiza classes;

  • administra saídas;

  • acompanha o processamento.

O JES2 não executa diretamente as instruções COBOL.

O fluxo correto é mais próximo de:

JES2 administra o job
Initiator inicia o step
z/OS prepara o ambiente
Loader carrega o módulo
Dispatcher entrega processador
CPU executa as instruções

Memória e CPU

O programa é carregado em um address space.

O Language Environment prepara o runtime.

O dispatcher distribui capacidade de processamento.

O WLM ajuda a priorizar workloads conforme objetivos de serviço.

A CPU não executa comandos COBOL como:

MOVE
READ
PERFORM
COMPUTE

Ela executa as instruções de máquina produzidas pelo compilador.

O capítulo também explica a diferença entre:

Tempo de CPU
Tempo decorrido

Um job pode permanecer dez minutos em execução e consumir apenas alguns segundos de CPU.

O restante pode ser espera por:

  • arquivos;

  • Db2;

  • IMS;

  • Adabas;

  • locks;

  • filas;

  • mensagens;

  • armazenamento;

  • rede.

Leia a Parte IV

https://eljefemidnightlunch.blogspot.com/2022/04/da-compilacao-execucao-de-um-programa.html


O que o Padawan aprende com a série

Ao concluir os quatro capítulos, o iniciante passa a compreender que um programa COBOL não é apenas um membro dentro de uma biblioteca.

Ele faz parte de uma cadeia maior.

Fonte
Copybook
Tradutor
Pré-compilador
Compilador
Objeto
Binder
Load
Package
JCL
JES2
Spool
Loader
Memória
CPU
Dados
Resultado

Essa visão permite investigar problemas com muito mais precisão.

Em vez de dizer:

“O programa não funciona”,

o profissional começa a perguntar:

  • O fonte correto foi compilado?

  • O copybook correto foi utilizado?

  • O CICS traduziu os comandos?

  • O DBRM foi gerado?

  • O package Db2 foi criado?

  • O Binder resolveu todas as referências?

  • O load foi gravado na biblioteca correta?

  • A STEPLIB aponta para essa biblioteca?

  • O DDNAME corresponde ao ASSIGN TO?

  • O dataset existe?

  • O FILE STATUS foi tratado?

  • O SQLCODE foi verificado?

  • O programa terminou com return code ou abend?

  • O tempo foi gasto em CPU ou em espera?

Essas perguntas transformam uma investigação baseada em tentativa e erro em um diagnóstico técnico estruturado.


A diferença entre escrever COBOL e entender o mainframe

Escrever COBOL é uma habilidade importante.

Mas compreender o ciclo completo de construção e execução é o que permite ao profissional atuar com segurança em ambientes corporativos.

O programador que conhece apenas o fonte pode corrigir uma linha.

O profissional que conhece o ecossistema consegue compreender:

  • por que uma alteração não chegou ao ambiente;

  • por que o programa antigo continua executando;

  • por que um package está incompatível;

  • por que o arquivo não abriu;

  • por que o job está aguardando;

  • por que o tempo decorrido aumentou;

  • por que a CPU não é a causa da lentidão;

  • por que uma recompilação em massa foi necessária;

  • por que um copybook deve ser tratado como contrato.

Esse é o verdadeiro objetivo da série.

Não ensinar apenas comandos.

Ensinar a enxergar o sistema completo.


Leia a série completa

Parte I

O Nascimento do Programa COBOL: Código-fonte e Copybooks

Parte II

CICS, Db2, IMS e Adabas: O Código Antes da Compilação

Parte III

Compilação, Linkedição e Load Library

Parte IV

Da Load Library à CPU: JCL, JES2, QSAM, VSAM e Execução


Conclusão

A jornada de um programa COBOL começa muito antes da execução.

Ela nasce na regra de negócio.

Ganha forma no código-fonte.

Reutiliza estruturas por meio de copybooks.

Conversa com CICS, Db2, IMS e Adabas.

É analisada pelo compilador.

Transforma-se em código objeto.

É reunida pelo Binder.

Torna-se um módulo executável.

É armazenada em uma load library.

Depois, um JCL, uma transação ou um subsistema solicita sua execução.

O JES2 administra o job.

O initiator inicia os steps.

O loader coloca o programa em memória.

O z/OS gerencia recursos.

O WLM orienta prioridades.

O dispatcher entrega capacidade de processamento.

A CPU executa as instruções.

QSAM, VSAM, Db2, IMS, CICS e Adabas fornecem os dados e serviços necessários.

Por fim, o programa produz relatórios, atualizações, mensagens, arquivos e resultados de negócio.

Nada simplesmente “roda”.

Tudo é preparado, ligado, controlado, carregado, executado e registrado.

“O Padawan observa o código-fonte. O especialista acompanha toda a jornada, desde o primeiro COPY até o último ciclo de CPU.”

 

Laboratório Forense Bellacosa Mainframe

CSI z/OS: Da Compilação à Execução de um Programa COBOL

Cinco arquivos de evidências revelam como o código-fonte COBOL atravessa copybooks, CICS, Db2, IMS, compilação, Binder, load library, JCL, JES2, memória e CPU até produzir um resultado no IBM Z.

CASO: COBOL-2022-EXEC EVIDÊNCIAS: 05 ARTIGOS AMBIENTE: IBM Z / z/OS STATUS: ARQUIVO ABERTO

Esta investigação técnica apresenta o ciclo completo de um programa COBOL no mainframe IBM Z. A série explica o nascimento do código-fonte, o uso de copybooks, a preparação de comandos CICS e SQL, a geração de código objeto, a atuação do Binder, o armazenamento em load libraries e a execução por JCL, JES2, loader, Language Environment, dispatcher e CPU. Selecione uma evidência abaixo para ler o artigo correspondente dentro do visualizador.

Evidência selecionada Parte I — Código-fonte, bibliotecas e copybooks
Processando evidência digital...

Laudo preliminar: o nascimento do programa

A primeira parte acompanha a transformação da regra de negócio em código-fonte COBOL, explica o papel das bibliotecas e mostra por que copybooks funcionam como contratos de dados compartilhados entre programas.

COBOL código-fonte copybook SYSLIB IBM Z
Bellacosa Mainframe Forensic Lab · Nenhum byte é inocente até que os logs provem o contrário.

terça-feira, 1 de março de 2022

Da Compilação à Execução de um Programa COBOL — Parte III

 

Bellacosa Mainframe compilacao cobol parte iii

☕ Um Café no Bellacosa Mainframe

Da Compilação à Execução de um Programa COBOL — Parte III

Compilação, Linkedição e Load Library: Como o Código-Fonte se Transforma em um Programa Executável

Introdução

Na segunda parte desta jornada, vimos que muitos programas COBOL corporativos não seguem diretamente para o compilador.

Antes disso, eles podem passar por outras etapas especializadas.

Comandos como:

EXEC CICS

precisam ser traduzidos.

Comandos como:

EXEC SQL

precisam ser processados pelo pré-compilador ou coprocessador Db2.

Programas IMS utilizam interfaces DL/I, PCBs, PSBs e DBDs.

Aplicações Adabas dependem de control blocks, buffers e módulos de comunicação.

Depois que todo esse material foi preparado, finalmente chega o momento em que o compilador COBOL entra em cena.

É aqui que o texto escrito pelo programador começa a se transformar em instruções realmente compreendidas pela máquina.

Entretanto, existe uma confusão muito comum entre iniciantes:

Compilar não significa necessariamente criar o executável final.

A compilação produz um código objeto.

Depois disso, outra ferramenta, chamada Binder, precisa reunir esse objeto com interfaces, rotinas e módulos necessários.

Esse processo é conhecido como linkedição.

Somente após a linkedição surge o módulo executável que poderá ser gravado em uma load library.

Nesta terceira parte, vamos acompanhar essa transformação passo a passo.

Prepare o café, abra o SDSF e venha entender o que realmente acontece entre o fonte COBOL e o módulo executável.


1. O que significa compilar?

Compilar significa transformar o código-fonte escrito pelo programador em código objeto.

O fluxo mais simples é:

Código-fonte COBOL
          ↓
Compilador COBOL
          ↓
Código objeto

O código-fonte é legível para seres humanos treinados em COBOL.

Exemplo:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. PGMCALC.

       DATA DIVISION.
       WORKING-STORAGE SECTION.

       01  WS-VALOR-A           PIC S9(09) COMP.
       01  WS-VALOR-B           PIC S9(09) COMP.
       01  WS-TOTAL             PIC S9(09) COMP.

       PROCEDURE DIVISION.

           MOVE 100 TO WS-VALOR-A
           MOVE 250 TO WS-VALOR-B

           COMPUTE WS-TOTAL =
                   WS-VALOR-A + WS-VALOR-B

           DISPLAY 'TOTAL: ' WS-TOTAL

           STOP RUN.

A CPU do IBM Z não executa diretamente instruções como:

MOVE
COMPUTE
DISPLAY
STOP RUN

Essas instruções precisam ser transformadas em instruções de máquina compatíveis com a arquitetura do processador.

O compilador realiza essa conversão.


2. O compilador faz muito mais do que traduzir

Muitos iniciantes imaginam que o compilador apenas troca comandos COBOL por instruções de máquina.

Na realidade, ele executa várias análises.

Entre elas:

  • verificação de sintaxe;

  • validação de nomes;

  • análise de tipos de dados;

  • cálculo de tamanhos;

  • validação de referências;

  • verificação de parágrafos;

  • resolução de campos;

  • tratamento de copybooks;

  • validação de arquivos;

  • análise de expressões;

  • geração de código;

  • otimização;

  • emissão de mensagens;

  • criação de listagens;

  • produção do módulo objeto.

Considere:

       01  WS-NOME              PIC X(40).
       01  WS-IDADE             PIC 9(03).

           MOVE WS-NOME TO WS-IDADE.

O compilador poderá identificar que um campo alfanumérico está sendo movido para um campo numérico.

Dependendo das opções e do conteúdo, isso poderá produzir:

  • advertência;

  • conversão;

  • risco de erro em execução;

  • mensagem de diagnóstico.

O compilador é, portanto, uma espécie de auditor técnico do programa.


3. O compilador precisa conhecer os copybooks

Na primeira parte, vimos que um programa pode utilizar:

       COPY CPYCLI01.

O compilador precisa localizar esse copybook.

Normalmente, as bibliotecas são indicadas por meio de um DD statement como:

//SYSLIB DD DISP=SHR,
//          DSN=EMPRESA.SISTEMA.COPYLIB

Pode haver várias bibliotecas:

//SYSLIB DD DISP=SHR,
//          DSN=EMPRESA.SISTEMA.COPYLIB
//       DD DISP=SHR,
//          DSN=EMPRESA.CORPORATIVO.COPYLIB
//       DD DISP=SHR,
//          DSN=FORNECEDOR.PRODUTO.COPYLIB

A ordem pode ser importante.

Se duas bibliotecas possuírem um membro com o mesmo nome, o primeiro encontrado poderá ser utilizado.

Imagine:

EMPRESA.TESTE.COPYLIB(CPYCLI01)
EMPRESA.PRODUCAO.COPYLIB(CPYCLI01)

Se a biblioteca errada estiver antes na concatenação, o programa poderá ser compilado com uma versão incorreta do layout.

O fonte estará correto.

O copybook existirá.

A compilação poderá terminar com sucesso.

Mesmo assim, o programa poderá utilizar uma estrutura incompatível.

Essa é uma das razões pelas quais o processo de compilação precisa ser controlado.


4. O compilador trabalha com opções

O comportamento do compilador pode ser alterado por opções.

Essas opções podem controlar:

  • geração de listagem;

  • otimização;

  • tratamento de chamadas;

  • compatibilidade;

  • informações de depuração;

  • aritmética;

  • encoding;

  • migração;

  • geração de dados de teste;

  • integração com CICS;

  • integração com Db2;

  • tratamento de warnings.

Exemplos de opções frequentemente encontradas em ambientes COBOL incluem conceitos como:

OPTIMIZE
LIST
MAP
XREF
SSRANGE
NUMCHECK
RENT
DYNAM
NODYNAM
TEST
ARCH
TUNE

Os nomes e efeitos exatos dependem da versão e da configuração do Enterprise COBOL.

O importante para o Padawan é entender:

O mesmo fonte pode gerar executáveis diferentes conforme as opções utilizadas.


5. Otimização

O compilador pode reorganizar ou melhorar o código gerado para produzir maior eficiência.

Considere:

           MULTIPLY WS-VALOR BY 2
               GIVING WS-RESULTADO.

O programador descreve a regra.

O compilador decide como representá-la em instruções de máquina.

Com opções de otimização, ele pode:

  • reduzir instruções;

  • eliminar operações desnecessárias;

  • reorganizar processamento;

  • utilizar recursos modernos da arquitetura;

  • melhorar acesso a dados;

  • produzir código mais eficiente.

Porém, níveis elevados de otimização podem tornar a depuração mais complexa.

O código gerado pode não seguir exatamente a ordem visual do fonte.

Por isso, ambientes de desenvolvimento e produção podem utilizar estratégias diferentes.


6. Opções de diagnóstico

Opções como validação de subscritos, verificação numérica e informações de teste podem ajudar a detectar problemas.

Imagine:

       01  TABELA-VALORES.
           05 ITEM-VALOR OCCURS 10 TIMES
                PIC 9(05).

       01  WS-INDICE             PIC 9(02).

           MOVE 15 TO WS-INDICE
           MOVE 100 TO ITEM-VALOR(WS-INDICE).

A tabela possui dez elementos.

O programa tenta acessar a posição quinze.

Sem verificações adequadas, o programa pode sobrescrever outra área de memória.

Com opções de runtime e compilação apropriadas, esse erro pode ser detectado.

Entretanto, verificações adicionais também podem consumir mais processamento.

Em produção, as empresas equilibram:

Segurança
Desempenho
Diagnóstico
Governança

7. O que é o código objeto?

O código objeto é o resultado principal da compilação.

Ele contém instruções de máquina e informações necessárias para a próxima fase.

Porém, ele ainda pode possuir referências externas.

Exemplo:

           CALL 'PGMVALID'
                USING WS-CPF
                      WS-RETORNO.

O compilador sabe que o programa possui uma referência a PGMVALID.

Dependendo do tipo de chamada e das opções utilizadas, essa referência poderá ser resolvida durante a linkedição ou durante a execução.

O objeto pode conter:

  • instruções de máquina;

  • áreas;

  • referências externas;

  • símbolos;

  • informações de relocação;

  • pontos de entrada;

  • dados necessários ao Binder.

Podemos pensar assim:

Código objeto = programa parcialmente montado

Ele já deixou de ser fonte, mas ainda pode não estar pronto para ser carregado.


8. O objeto não é o executável final

Essa é uma das maiores confusões entre iniciantes.

Depois da compilação, o programa ainda pode precisar de:

  • interfaces CICS;

  • interfaces Db2;

  • interfaces IMS;

  • módulos Adabas;

  • rotinas estáticas;

  • bibliotecas de suporte;

  • módulos de linguagem;

  • pontos de entrada;

  • resolução de referências.

Por isso, o processo continua:

Código objeto
      ↓
Binder
      ↓
Módulo executável

A compilação produz peças.

A linkedição reúne as peças.


9. O que é linkedição?

Linkedição é o processo de combinar o código objeto com outros módulos e referências para criar uma unidade executável.

Em inglês, você poderá encontrar termos como:

Link-edit
Linkage edition
Binding

Em ambientes modernos, a ferramenta principal é o Binder do z/OS.

Em documentações antigas, também aparece o termo Linkage Editor.

Podemos representar assim:

Objeto do programa principal
           +
Rotinas externas
           +
Interfaces de subsistemas
           +
Módulos estáticos
           +
Pontos de entrada
           ↓
Binder
           ↓
Módulo executável

10. O Binder do z/OS

O Binder é responsável por organizar e combinar os módulos recebidos.

Ele pode:

  • resolver referências externas;

  • incluir módulos;

  • definir pontos de entrada;

  • organizar seções;

  • produzir mapas;

  • gerar referências cruzadas;

  • identificar símbolos não resolvidos;

  • criar load modules;

  • criar program objects;

  • gravar o resultado em uma biblioteca executável.

Um JCL tradicional pode utilizar:

//LKED EXEC PGM=IEWL

O nome IEWL possui origem histórica no Linkage Editor.

Mesmo com a evolução para o Binder, ele continua aparecendo em muitos JCLs e procedures.


11. Um exemplo simples de compilação

Um JCL conceitual de compilação poderia ser:

//COMPILA  JOB (1234),'BELLACOSA',
//             CLASS=A,
//             MSGCLASS=X,
//             NOTIFY=&SYSUID
//*
//COBOL    EXEC PGM=IGYCRCTL
//STEPLIB  DD DISP=SHR,
//            DSN=IGY.V6R5M0.SIGYCOMP
//SYSIN    DD DISP=SHR,
//            DSN=EMPRESA.SISTEMA.COBOL(PGMCLI01)
//SYSLIB   DD DISP=SHR,
//            DSN=EMPRESA.SISTEMA.COPYLIB
//SYSLIN   DD DISP=(NEW,PASS),
//            DSN=&&OBJ,
//            UNIT=SYSDA,
//            SPACE=(TRK,(5,5))
//SYSPRINT DD SYSOUT=*
//SYSUT1   DD UNIT=SYSDA,
//            SPACE=(CYL,(1,1))

Esse exemplo é simplificado.

O compilador lê o fonte em:

//SYSIN

Procura copybooks em:

//SYSLIB

Produz o objeto em:

//SYSLIN

Gera a listagem em:

//SYSPRINT

O dataset:

&&OBJ

é temporário.

Os dois sinais de && indicam um dataset temporário associado ao job.

O parâmetro:

DISP=(NEW,PASS)

significa que ele é criado nessa etapa e passado para a próxima.


12. A etapa de linkedição

Depois da compilação:

//LKED     EXEC PGM=IEWL,
//            PARM='LIST,MAP,XREF'
//SYSLIN   DD DISP=(OLD,DELETE),
//            DSN=&&OBJ
//SYSLMOD  DD DISP=SHR,
//            DSN=EMPRESA.SISTEMA.LOADLIB(PGMCLI01)
//SYSPRINT DD SYSOUT=*

O Binder recebe o objeto por meio de:

//SYSLIN

O resultado é gravado em:

//SYSLMOD

Nesse exemplo:

EMPRESA.SISTEMA.LOADLIB(PGMCLI01)

será o módulo executável.

A saída de diagnóstico será enviada para:

//SYSPRINT

13. O papel de SYSLIN e SYSLMOD

Esses DDNAMEs aparecem frequentemente em processos de linkedição.

SYSLIN

Contém a entrada para o Binder.

Pode incluir:

  • objetos;

  • control statements;

  • referências;

  • comandos INCLUDE;

  • instruções de entrada.

SYSLMOD

Define onde o módulo executável será gravado.

Exemplo:

//SYSLMOD DD DISP=SHR,
//           DSN=EMPRESA.TESTE.LOADLIB(PGMCLI01)

Podemos resumir:

SYSLIN  → entra objeto
SYSLMOD → sai executável

14. Comandos do Binder

O Binder pode receber comandos de controle.

Exemplo conceitual:

ENTRY PGMCLI01
NAME PGMCLI01(R)

O comando ENTRY pode definir o ponto inicial do programa.

O comando NAME pode indicar o nome do módulo que será criado.

Também podem existir comandos como:

INCLUDE
ALIAS
REPLACE
RENAME
SETCODE

A utilização varia conforme o processo e a arquitetura da aplicação.

Em muitas empresas, esses comandos ficam escondidos dentro de procedures ou ferramentas de build.


15. O que é ponto de entrada?

O ponto de entrada representa o local pelo qual a execução começa dentro do módulo.

Em um programa COBOL simples, isso normalmente é definido automaticamente.

Entretanto, módulos mais complexos podem possuir:

  • mais de um ponto de entrada;

  • aliases;

  • rotinas reutilizáveis;

  • estruturas compostas;

  • entry points adicionais.

Em COBOL, também existe a instrução:

       ENTRY 'OUTROENT'
           USING AREA-DADOS.

Esse recurso cria pontos adicionais de entrada em um programa.

Seu uso deve ser controlado, pois pode tornar a manutenção mais complexa.


16. Chamadas estáticas

Considere:

           CALL 'PGMVALID'
                USING WS-DADOS.

Em uma chamada estática, o módulo chamado é resolvido durante a linkedição.

O Binder precisa localizar PGMVALID.

Ele poderá incorporá-lo ou ligá-lo ao módulo principal.

Fluxo:

Objeto PGMCLI01
       +
Objeto ou módulo PGMVALID
       ↓
Binder
       ↓
Executável combinado

Vantagens da chamada estática:

  • resolução antecipada;

  • menor risco de programa não encontrado em runtime;

  • controle sobre a versão ligada;

  • menos busca dinâmica.

Desvantagens:

  • alteração no subprograma pode exigir relinkedição;

  • executável pode crescer;

  • vários chamadores podem precisar ser atualizados;

  • maior acoplamento entre módulos.


17. Chamadas dinâmicas

Em uma chamada dinâmica, o módulo é localizado durante a execução.

Exemplo com nome variável:

       01  WS-PROGRAMA          PIC X(08).

           MOVE 'PGMVALID' TO WS-PROGRAMA

           CALL WS-PROGRAMA
                USING WS-DADOS.

O nome está em uma variável.

Isso caracteriza uma chamada dinâmica.

Dependendo das opções do compilador, chamadas literais também podem ser tratadas dinamicamente.

O módulo não precisa ser incorporado ao chamador durante a linkedição.

Na execução, o sistema procurará PGMVALID nas bibliotecas disponíveis.

Vantagens:

  • atualização independente;

  • maior reutilização;

  • executável principal menor;

  • menor necessidade de relinkedição.

Desvantagens:

  • o programa pode não ser encontrado;

  • bibliotecas precisam estar corretas;

  • versões incompatíveis podem causar falhas;

  • o problema aparece somente em execução.


18. DYNAM e NODYNAM

Opções de compilação podem influenciar o tratamento das chamadas.

Conceitualmente:

DYNAM   → favorece chamadas dinâmicas
NODYNAM → permite resolução estática de chamadas literais

O comportamento exato depende da forma da chamada e das opções utilizadas.

Um iniciante não deve apenas decorar os nomes.

É melhor compreender a pergunta principal:

O módulo chamado será ligado agora ou procurado durante a execução?

Essa resposta influencia:

  • tamanho do executável;

  • implantação;

  • dependências;

  • manutenção;

  • diagnóstico.


19. O que acontece quando uma referência não é resolvida?

Imagine que o programa possui:

           CALL 'PGMVALID'
                USING WS-DADOS.

O Binder espera localizar o módulo, mas ele não está nas bibliotecas informadas.

Pode ocorrer uma referência externa não resolvida.

O Binder poderá emitir mensagens indicando:

  • símbolo não encontrado;

  • módulo ausente;

  • biblioteca incorreta;

  • erro na resolução;

  • ponto de entrada inexistente.

Dependendo das opções, o processo poderá:

  • terminar com erro;

  • gerar módulo incompleto;

  • permitir execução com risco;

  • impedir a gravação do executável.

Por isso, a listagem do Binder precisa ser analisada.


20. Bibliotecas de objetos e módulos

O processo pode utilizar bibliotecas como:

EMPRESA.SISTEMA.OBJLIB
EMPRESA.SISTEMA.LOADLIB
EMPRESA.COMUM.LOADLIB
PRODUTO.INTERFACE.LOADLIB

OBJLIB

Pode armazenar módulos objeto.

Nem todas as empresas mantêm objetos permanentemente.

Algumas utilizam datasets temporários.

LOADLIB

Armazena módulos executáveis.

Bibliotecas comuns

Podem conter:

  • rotinas reutilizáveis;

  • interfaces;

  • subprogramas;

  • componentes corporativos;

  • módulos de fornecedores.

O Binder recebe essas bibliotecas por DD statements específicos, muitas vezes como:

//SYSLIB DD DISP=SHR,
//          DSN=EMPRESA.COMUM.LOADLIB

21. Load module e program object

Durante décadas, o termo tradicional foi load module.

Com a evolução do z/OS e das bibliotecas PDSE, tornou-se comum utilizar program objects.

Um iniciante poderá ouvir:

  • load;

  • load module;

  • módulo de carga;

  • program object;

  • executável;

  • membro da loadlib.

Embora existam diferenças técnicas de formato e capacidade, todos representam o mesmo conceito geral:

Um artefato preparado para ser localizado, carregado e executado.

O program object moderno pode suportar recursos que os antigos load modules não suportavam da mesma forma.

Porém, no cotidiano, muitos profissionais continuam chamando tudo simplesmente de “load”.


22. A load library

A load library é uma biblioteca que contém módulos executáveis.

Exemplo:

EMPRESA.SISTEMA.LOADLIB

Membros:

PGMCLI01
PGMCLI02
PGMCALC
PGMREL01
PGMVALID

Ao abrir essa biblioteca no ISPF, o conteúdo não será um fonte COBOL legível.

Ela contém estruturas binárias.

O programador normalmente não edita diretamente um load module.

A alteração correta é feita no fonte.

Depois disso, o programa é recompilado e linkedidado.


23. Fonte, objeto e load

É importante visualizar a diferença.

Fonte

EMPRESA.SISTEMA.COBOL(PGMCLI01)

Contém código COBOL.

Objeto

EMPRESA.SISTEMA.OBJLIB(PGMCLI01)

Contém o resultado intermediário da compilação.

Load

EMPRESA.SISTEMA.LOADLIB(PGMCLI01)

Contém o módulo executável.

O mesmo nome pode existir em bibliotecas diferentes.

Isso não significa que sejam o mesmo tipo de conteúdo.


24. O perigo de executar a versão errada

Imagine que o programador compile uma nova versão em:

EMPRESA.TESTE.LOADLIB(PGMCLI01)

Porém, o JCL de teste utiliza:

//STEPLIB DD DISP=SHR,
//           DSN=EMPRESA.ANTIGA.LOADLIB

O job executará a versão antiga.

O programador poderá dizer:

“Minha alteração não funcionou.”

Na realidade, o programa correto nunca foi carregado.

Esse problema é extremamente comum.

Sempre verifique:

  • onde o load foi gravado;

  • qual biblioteca está no JCL;

  • qual biblioteca está primeiro na concatenação;

  • se existe outro membro com o mesmo nome;

  • se o ambiente online carregou a nova versão.


25. Linkedição de programas CICS

Um programa CICS precisa ser preparado com as interfaces necessárias.

Historicamente, a linkedição poderia incluir módulos específicos do CICS.

Dependendo da arquitetura e versão, o processo pode utilizar stubs ou interfaces fornecidas pelo produto.

Além disso, o executável precisa ser disponibilizado em uma biblioteca acessível à região CICS.

Normalmente, encontramos referências a bibliotecas concatenadas na DFHRPL.

Fluxo simplificado:

Fonte CICS
    ↓
Tradução
    ↓
Compilação
    ↓
Linkedição com interfaces CICS
    ↓
Load library
    ↓
Biblioteca acessível ao CICS

Depois, o CICS precisa reconhecer ou atualizar o programa em execução.

Pode ser necessário utilizar recursos como:

  • new copy;

  • phase-in;

  • atualização de definição;

  • pipeline de deployment;

  • refresh do programa.


26. Linkedição de programas Db2

Programas Db2 também utilizam interfaces de conexão.

Um programa batch Db2 pode ser linkedidado com componentes apropriados para o método de conexão utilizado.

Além disso, o DBRM precisa passar pelo BIND.

Portanto, existem dois resultados:

Load module COBOL
Package Db2

Os dois precisam estar compatíveis.

Podem ocorrer problemas como:

  • load novo com package antigo;

  • package novo com load antigo;

  • collection incorreta;

  • plano incorreto;

  • versão incompatível;

  • módulo em biblioteca errada.

Esse tipo de situação mostra por que a implantação precisa coordenar artefatos.


27. Linkedição de programas IMS

Programas IMS podem precisar de interfaces DL/I durante a linkedição.

O método exato varia conforme:

  • tipo de região;

  • forma de execução;

  • ambiente IMS;

  • linguagem;

  • procedures da empresa.

O módulo executável também precisa ser chamado em conjunto com o PSB adequado.

Isso significa que a execução depende de:

Load module
PSB
PCBs
DBDs
Ambiente IMS

O load sozinho não representa toda a aplicação.


28. Linkedição de programas Adabas

Programas COBOL que acessam Adabas precisam das interfaces correspondentes.

Durante a linkedição, módulos de comunicação e bibliotecas fornecidas pelo ambiente podem ser incluídos ou referenciados.

Na execução, o programa utilizará essas interfaces para se comunicar com o Adabas Nucleus.

Assim como nos demais subsistemas:

Programa COBOL + interface especializada = acesso ao serviço

29. Procedures catalogadas

Em muitas empresas, o programador não escreve manualmente o JCL completo de compilação e linkedição.

Ele utiliza uma procedure catalogada.

Exemplo:

//COMPILA EXEC PROC=COBOLCL

Ou:

//COMPILA EXEC PROC=COB2CL

Ou:

//COMPILA EXEC PROC=COBCICS

A procedure pode esconder:

  • tradução;

  • pré-compilação;

  • compilação;

  • linkedição;

  • BIND;

  • bibliotecas;

  • opções;

  • datasets temporários;

  • controles corporativos.

O Padawan vê uma única linha.

Por trás dela podem existir dezenas de etapas.


30. O que é uma procedure catalogada?

Uma procedure catalogada é um conjunto reutilizável de instruções JCL armazenado em uma biblioteca de procedures.

Exemplo conceitual:

SYS1.PROCLIB
EMPRESA.PROCLIB

Dentro dela:

COBOLCL
COBDB2
COBCICS
COBIMS

A procedure permite padronizar o processo.

Benefícios:

  • evita duplicação;

  • centraliza opções;

  • facilita manutenção;

  • reduz erros;

  • garante bibliotecas corretas;

  • padroniza retorno;

  • integra ferramentas corporativas.

Porém, também pode esconder detalhes.

Por isso, o iniciante deve aprender a abrir e analisar a procedure.


31. Parâmetros simbólicos

Procedures podem utilizar parâmetros.

Exemplo conceitual:

//COMPILA EXEC COBOLCL,
//             MEMBER=PGMCLI01,
//             SRCLIB=EMPRESA.SISTEMA.COBOL,
//             LOADLIB=EMPRESA.SISTEMA.LOADLIB

Dentro da procedure, podem existir símbolos como:

&MEMBER
&SRCLIB
&LOADLIB

Quando o job é submetido, esses símbolos são substituídos.

Isso permite utilizar a mesma procedure para vários programas.


32. Compilação local, pipeline e ferramentas modernas

Nem todo processo moderno é iniciado manualmente por JCL.

Empresas podem utilizar:

  • IBM Developer for z/OS;

  • IBM Z Open Editor;

  • VS Code;

  • Git;

  • Jenkins;

  • IBM Dependency Based Build;

  • zBuilder;

  • UrbanCode Deploy;

  • Endevor;

  • ISPW;

  • ferramentas internas;

  • pipelines CI/CD.

O desenvolvedor altera o fonte e aciona um pipeline.

O pipeline pode:

  1. detectar dependências;

  2. identificar copybooks alterados;

  3. traduzir CICS;

  4. processar SQL;

  5. compilar COBOL;

  6. linkeditar;

  7. executar testes;

  8. gerar evidências;

  9. promover artefatos;

  10. implantar o load.

Mesmo com automação, os fundamentos continuam iguais.

A ferramenta não elimina as etapas.

Ela apenas as coordena.


33. Análise de impacto de copybook

Imagine que CPYCLI01 seja usado por cem programas.

Uma alteração foi realizada:

       05 CLI-LIMITE PIC S9(13)V99 COMP-3.

Antes:

       05 CLI-LIMITE PIC S9(11)V99 COMP-3.

Os programas dependentes podem precisar ser recompilados.

Uma ferramenta de build baseada em dependências pode identificar:

CPYCLI01 alterado
      ↓
PGMCLI01 afetado
PGMCLI02 afetado
PGMREL01 afetado
PGMCRD01 afetado

Esse processo evita que apenas um módulo seja recompilado enquanto outros continuam utilizando o layout antigo.


34. Return codes da compilação

Durante a compilação, o job pode terminar com códigos como:

RC=0000
RC=0004
RC=0008
RC=0012
RC=0016

Uma interpretação geral:

RC 0

Nenhum erro relevante foi encontrado.

RC 4

Foram geradas advertências.

O programa pode ter sido produzido, mas as mensagens precisam ser analisadas.

RC 8

Existem erros significativos.

Em muitos processos, a linkedição não deve continuar.

RC 12

Erros graves impediram a geração correta.

RC 16

Falha severa, problema estrutural ou impossibilidade de processamento.

Os significados exatos dependem da etapa e das mensagens.

Nunca utilize apenas o número como diagnóstico completo.


35. O perigo do RC 4

O programador pode pensar:

“RC 4 é normal.”

Às vezes, a advertência é realmente conhecida.

Mas um RC 4 pode indicar:

  • campo não utilizado;

  • conversão perigosa;

  • valor truncado;

  • incompatibilidade de tipo;

  • comportamento obsoleto;

  • opção ignorada;

  • possível erro lógico;

  • recurso que mudará em versões futuras.

Em sistemas críticos, advertências precisam ser classificadas.

O objetivo não é aceitar tudo nem rejeitar tudo.

O objetivo é compreender.


36. Return code do Binder

A linkedição também produz return code.

Problemas podem incluir:

  • referência externa não resolvida;

  • módulo ausente;

  • biblioteca indisponível;

  • símbolo duplicado;

  • erro de ponto de entrada;

  • espaço insuficiente;

  • formato incompatível;

  • opção inválida.

O Binder pode gerar o módulo mesmo com algumas advertências.

Porém, isso não significa que o executável esteja seguro.

Leia:

  • mensagens;

  • map;

  • cross-reference;

  • entry point;

  • unresolved references;

  • bibliotecas utilizadas.


37. MAP e XREF

Opções como:

MAP
XREF
LIST

podem gerar informações úteis.

MAP

Mostra o mapa do módulo.

Pode ajudar a entender:

  • seções;

  • tamanhos;

  • endereços relativos;

  • módulos incluídos;

  • organização do executável.

XREF

Mostra referências cruzadas.

Ajuda a identificar:

  • símbolos;

  • definições;

  • referências;

  • módulos que fornecem determinados nomes.

Essas informações são valiosas na investigação de problemas de linkedição.


38. Erros de compilação mais comuns

Entre os erros frequentes:

  • campo não definido;

  • palavra reservada usada incorretamente;

  • parágrafo inexistente;

  • END-IF ausente;

  • ponto final em posição incorreta;

  • copybook não encontrado;

  • PIC inválida;

  • nível hierárquico incorreto;

  • variável incompatível;

  • arquivo sem definição adequada;

  • SQL ou CICS não processado.

Exemplo:

           MOVE WS-VALOR TO WS-CAMPO-INEXISTENTE.

O compilador identifica a referência inexistente.


39. Erros de linkedição mais comuns

Entre os erros frequentes:

  • subprograma estático ausente;

  • biblioteca não concatenada;

  • módulo com nome diferente;

  • interface de subsistema ausente;

  • símbolo externo não resolvido;

  • entrada incorreta;

  • módulo incompatível;

  • control statements incorretos.

Exemplo:

           CALL 'PGMCALC'

Mas a biblioteca possui:

PGMCAL01

O nome não corresponde.

A resolução poderá falhar.


40. Erro de compilação não é erro de execução

É importante separar as fases.

Compilação

Analisa e traduz o fonte.

Linkedição

Monta o executável.

Carga

Localiza o módulo durante a execução.

Runtime

Executa a lógica e acessa dados.

Um problema pode ocorrer em qualquer uma dessas etapas.

Exemplo:

Fonte correto
Compilação RC 0
Linkedição RC 0
Execução S806

Nesse caso, o programa foi criado, mas o sistema não o encontrou na biblioteca de execução.

Outro exemplo:

Compilação RC 0
Linkedição RC 0
Programa executado
FILE STATUS 35

O executável está correto, mas o arquivo não foi localizado ou aberto.

Diagnóstico correto começa pela identificação da fase.


41. O Language Environment

Programas COBOL modernos no z/OS normalmente executam sob o Language Environment.

O Language Environment fornece serviços comuns para linguagens como:

  • COBOL;

  • PL/I;

  • C;

  • C++.

Ele participa de:

  • inicialização;

  • gerenciamento de memória;

  • parâmetros;

  • tratamento de condições;

  • mensagens;

  • datas;

  • conversões;

  • finalização;

  • dumps;

  • interoperabilidade.

Durante a linkedição e execução, o programa pode depender de componentes do Language Environment.

Mensagens iniciadas por:

CEE

frequentemente estão relacionadas a esse ambiente.


42. RENT e programas reentrantes

Programas online, especialmente CICS, costumam precisar ser reentrantes.

Um programa reentrante pode ser compartilhado com segurança por várias tasks, desde que não modifique indevidamente áreas comuns de código ou dados.

A opção:

RENT

está associada à geração de código reentrante.

Isso é importante porque o CICS pode atender milhares de transações concorrentes.

O código pode ser compartilhado, enquanto cada task possui suas áreas de trabalho apropriadas.

Um programa não reentrante pode causar:

  • corrupção de dados;

  • interferência entre usuários;

  • resultados imprevisíveis;

  • falhas de integridade.


43. O perigo de armazenar estado no lugar errado

Imagine um programa CICS que mantém dados mutáveis em uma área compartilhada de forma incorreta.

Duas tasks podem executar o mesmo módulo simultaneamente.

A task A altera uma informação.

A task B enxerga ou sobrescreve essa mesma informação.

O resultado pode ser uma mistura de dados entre transações.

Por isso, programas online utilizam estruturas como:

  • COMMAREA;

  • channels e containers;

  • working-storage gerenciado adequadamente;

  • áreas fornecidas pelo CICS;

  • TSQ;

  • contextos transacionais.

A reentrância não é apenas uma opção técnica.

É uma garantia de convivência segura entre múltiplas execuções.


44. Versionamento do load

Em ambientes corporativos, o load module precisa ser controlado.

Perguntas importantes:

  • Qual fonte gerou o load?

  • Qual versão do copybook foi usada?

  • Qual compilador foi utilizado?

  • Quais opções foram aplicadas?

  • Qual pipeline gerou o módulo?

  • Qual commit corresponde ao executável?

  • Qual package Db2 foi associado?

  • Quando o load foi implantado?

  • Quem aprovou a promoção?

Sem rastreabilidade, o executável vira uma caixa-preta.


45. Programa compilado não significa programa testado

Uma compilação com RC 0 prova apenas que o compilador conseguiu processar o fonte.

Ela não prova que:

  • a regra de negócio está correta;

  • os dados foram tratados corretamente;

  • o SQL possui bom desempenho;

  • o arquivo está definido corretamente;

  • a transação CICS funciona;

  • o programa IMS utiliza o segmento correto;

  • o código Adabas trata todos os retornos;

  • o módulo não causa abend;

  • o programa atende ao requisito.

Compilação é uma etapa de validação técnica.

Teste é outra disciplina.


46. Um fluxo moderno de build

Um pipeline moderno pode executar:

Checkout do fonte
       ↓
Análise de dependências
       ↓
Expansão e localização de copybooks
       ↓
Tradução CICS
       ↓
Processamento Db2
       ↓
Compilação COBOL
       ↓
Linkedição
       ↓
BIND package
       ↓
Testes unitários
       ↓
Análise de qualidade
       ↓
Empacotamento
       ↓
Implantação

Esse fluxo parece moderno, mas continua baseado nos mesmos fundamentos utilizados há décadas.

O que mudou foi o nível de automação.


47. Exemplo completo do caminho até o load

Imagine o programa:

PGMCLI01

Ele utiliza:

CPYCLI01
EXEC CICS
EXEC SQL
CALL PGMVALID

O processo poderá ser:

1. Ler PGMCLI01
2. Localizar CPYCLI01
3. Traduzir EXEC CICS
4. Processar EXEC SQL
5. Gerar DBRM
6. Compilar o fonte preparado
7. Gerar objeto PGMCLI01
8. Localizar PGMVALID
9. Incluir interfaces CICS e Db2
10. Executar o Binder
11. Gravar PGMCLI01 na LOADLIB
12. Executar BIND do DBRM
13. Criar package Db2

Ao final:

EMPRESA.SISTEMA.LOADLIB(PGMCLI01)

e:

Package Db2 de PGMCLI01

estarão prontos para a próxima fase.


48. Checklist do Programador COBOL Padawan

Antes de declarar que o programa está pronto, verifique:

  • O fonte correto foi compilado?

  • Os copybooks corretos foram utilizados?

  • A biblioteca de copybooks estava na ordem certa?

  • Houve tradução CICS?

  • O SQL foi processado?

  • O DBRM foi gerado?

  • O package foi criado?

  • O compilador terminou com qual RC?

  • Existem warnings?

  • O Binder resolveu todas as referências?

  • O load foi gravado na biblioteca correta?

  • As chamadas são estáticas ou dinâmicas?

  • Os módulos chamados estão disponíveis?

  • A versão do load corresponde ao fonte?

  • Os testes foram executados?

  • A implantação utilizará a mesma load library?

Esse checklist evita muitos problemas que parecem misteriosos.


49. O grande mapa mental da Parte III

Podemos resumir toda a transformação:

Fonte preparado
      ↓
Compilador COBOL
      ↓
Validação
      ↓
Geração de instruções
      ↓
Código objeto
      ↓
Binder
      ↓
Resolução de referências
      ↓
Inclusão de módulos
      ↓
Definição do ponto de entrada
      ↓
Load module ou program object
      ↓
Load library

Em paralelo, quando houver Db2:

DBRM
  ↓
BIND
  ↓
Package

50. Uma analogia com uma fábrica

Imagine uma fábrica de automóveis.

O código-fonte é o projeto do veículo.

Os copybooks são padrões de componentes:

  • medidas;

  • conectores;

  • peças;

  • encaixes.

O compilador transforma o projeto em peças reais.

Ele produz:

  • motor;

  • chassis;

  • painel;

  • sistemas de controle.

Entretanto, as peças ainda estão separadas.

O Binder é a linha de montagem.

Ele reúne:

  • objeto principal;

  • módulos externos;

  • interfaces;

  • componentes;

  • pontos de entrada.

O resultado é o veículo montado.

A load library é o pátio onde os veículos prontos ficam armazenados.

Porém, o carro ainda não saiu do pátio.

Ele ainda precisa ser localizado, ligado e colocado na estrada.

Essa será a missão do próximo capítulo.


51. Conselhos do Mestre Bellacosa

Nunca trate a compilação como um botão misterioso.

Abra as listagens.

Leia as mensagens.

Entenda a procedure.

Descubra:

  • qual compilador foi utilizado;

  • quais opções foram aplicadas;

  • quais bibliotecas foram concatenadas;

  • quais copybooks foram encontrados;

  • quais módulos foram incluídos;

  • onde o objeto foi gravado;

  • onde o load foi criado;

  • quais referências foram resolvidas;

  • quais warnings foram emitidos.

O profissional que entende o processo de build investiga problemas com muito mais precisão.

Ele não diz apenas:

“A compilação falhou.”

Ele diz:

“O pré-processamento terminou corretamente, mas o Binder não resolveu o módulo estático porque a biblioteca de interfaces não estava na concatenação de SYSLIB.”

Esse é o tipo de compreensão que transforma um Padawan em especialista.


Conclusão

A compilação é o processo que transforma o código-fonte COBOL em código objeto.

Durante essa etapa, o compilador verifica sintaxe, campos, tipos de dados, referências, estruturas, opções e dependências.

O código objeto já contém instruções de máquina, mas ainda pode possuir referências externas.

Por isso, ele precisa passar pelo Binder.

A linkedição combina o objeto com módulos, interfaces e rotinas necessárias, resolvendo referências e criando um módulo executável.

Esse resultado é armazenado em uma load library.

Também aprendemos que chamadas podem ser estáticas ou dinâmicas.

Chamadas estáticas são resolvidas durante a linkedição.

Chamadas dinâmicas são localizadas durante a execução.

Vimos ainda que CICS, Db2, IMS e Adabas podem exigir interfaces específicas, e que o programa Db2 precisa coordenar dois artefatos fundamentais:

Load module
Package Db2

Ao final dessa etapa, o programa finalmente existe como executável.

Mas ele ainda está parado dentro de uma biblioteca.

Ele não abriu arquivos.

Não leu registros.

Não consultou tabelas.

Não consumiu CPU.

Não produziu relatórios.

A última etapa da jornada está prestes a começar.

No próximo capítulo

Na Parte IV — Da Load Library à CPU, vamos acompanhar o módulo durante a execução.

Veremos passo a passo:

  • como o JCL solicita a execução;

  • como a STEPLIB localiza o programa;

  • como QSAM e VSAM são conectados por DDNAME;

  • como o JES2 recebe e organiza o job;

  • o que é spool;

  • como o initiator inicia o processamento;

  • como o loader coloca o programa na memória;

  • como WLM e dispatcher participam;

  • como a CPU executa as instruções;

  • por que tempo de CPU é diferente de tempo decorrido;

  • como programas CICS, Db2, IMS e Adabas executam no ambiente real.

Prepare a quarta xícara de café.

O programa já nasceu, foi traduzido, compilado e linkedidado.

Agora chegou o momento de fazê-lo trabalhar.

“O Padawan acredita que a compilação cria o programa. O especialista sabe que a compilação cria as peças, a linkedição monta a máquina e a execução provará se toda a engenharia realmente funciona.”

Laboratório Forense Bellacosa Mainframe

CSI z/OS: Da Compilação à Execução de um Programa COBOL

Cinco arquivos de evidências revelam como o código-fonte COBOL atravessa copybooks, CICS, Db2, IMS, compilação, Binder, load library, JCL, JES2, memória e CPU até produzir um resultado no IBM Z.

CASO: COBOL-2022-EXEC EVIDÊNCIAS: 05 ARTIGOS AMBIENTE: IBM Z / z/OS STATUS: ARQUIVO ABERTO

Esta investigação técnica apresenta o ciclo completo de um programa COBOL no mainframe IBM Z. A série explica o nascimento do código-fonte, o uso de copybooks, a preparação de comandos CICS e SQL, a geração de código objeto, a atuação do Binder, o armazenamento em load libraries e a execução por JCL, JES2, loader, Language Environment, dispatcher e CPU. Selecione uma evidência abaixo para ler o artigo correspondente dentro do visualizador.

Evidência selecionada Parte I — Código-fonte, bibliotecas e copybooks
Processando evidência digital...

Laudo preliminar: o nascimento do programa

A primeira parte acompanha a transformação da regra de negócio em código-fonte COBOL, explica o papel das bibliotecas e mostra por que copybooks funcionam como contratos de dados compartilhados entre programas.

COBOL código-fonte copybook SYSLIB IBM Z
Bellacosa Mainframe Forensic Lab · Nenhum byte é inocente até que os logs provem o contrário.
Vagner Renato Bellacosa, IBM Champion e especialista em IBM Mainframe
IBM Z17 SYSTEM ONLINE
Sobre o autor

Vagner Renato Bellacosa

IBM Champion 2026 • Especialista em IBM Mainframe

Vagner Renato Bellacosa trabalha com IBM Mainframe desde 1988 , é IBM Champion e especialista em COBOL, CICS, Db2, z/OS e IBM Z. Compartilha experiências profissionais, conhecimento técnico, história da computação e práticas do universo mainframe para aproximar novas gerações das tecnologias que sustentam empresas, bancos e governos ao redor do mundo.

IBM Champion IBM Z COBOL CICS Db2 z/OS Mainframe desde 1988
GitHub LinkedIn
Inicializando conteúdo...