Articulo de referencia

GOFF

La especificación GOFF (Generalized Object File Format) se desarrolló para el sistema operativo MVS de IBM con el fin de reemplazar el formato de archivo de objeto de IBM OS/360...

La especificación GOFF (Generalized Object File Format) se desarrolló para el sistema operativo MVS de IBM con el fin de reemplazar el formato de archivo de objeto de IBM OS/360 y compensar las deficiencias del formato anterior. [ 1 ]

Fondo

El formato de archivo de objeto original de IBM OS/360 se desarrolló en 1964 para el nuevo ordenador central IBM System/360 . Este formato también fue utilizado por fabricantes de ordenadores centrales compatibles y similares, como los Univac 90/60, 90/70 y 90/80, y el Fujitsu B2800. El formato se amplió para incluir registros simbólicos e información ampliada sobre módulos, además de compatibilidad con procedimientos y funciones con nombres de más de 8 caracteres. Si bien esto resultó útil, no proporcionó la información avanzada necesaria para los lenguajes de programación más complejos de la actualidad ni para funciones más avanzadas como objetos, propiedades y métodos, compatibilidad con Unicode y métodos virtuales .

El formato de archivo objeto GOFF fue desarrollado por IBM aproximadamente en 1995 para superar estos problemas. [ 2 ] La primera mención de este formato se encuentra en la información introductoria sobre el nuevo ensamblador de alto nivel. [ 3 ] GOFF admite información de depuración integrada en el formato de datos asociados (ADATA), pero no admite los registros SYM antiguos generados por la opción TEST. Cabe señalar que el formato de archivo objeto OS/360 simplemente fue reemplazado por el formato GOFF, no fue declarado obsoleto, y aún lo utilizan los ensambladores y compiladores de lenguajes cuando el lenguaje puede soportar las limitaciones del formato anterior.

Convenciones

Este artículo utilizará el término «módulo» para referirse a cualquier nombre o símbolo equivalente que se utilice para proporcionar un identificador para un fragmento de código o datos externos al ámbito al que se hace referencia. [ a ] Un módulo puede referirse a una subrutina, una función, datos comunes o de bloque de Fortran , un objeto o clase, un método o propiedad de un objeto o clase, o cualquier otra rutina o identificador con nombre externo a ese ámbito particular que haga referencia al nombre externo. Tenga en cuenta que el uso de «módulo» en este artículo se utiliza para facilitar la comprensión del tema, pero no es lo mismo que el uso que IBM le da al término «módulo».

Los términos "ensamblador" se refieren a un programa que convierte el lenguaje ensamblador en código máquina , así como "ensamblar" al proceso de usar uno, y "compilar" al proceso de usar un " compilador ", que hace lo mismo para lenguajes de alto nivel; para los fines de este artículo, "compilar" y "compilador" son intercambiables con "ensamblar" y "ensamblador".

Los números utilizados en este artículo se expresan de la siguiente manera: a menos que se especifique que son hexadecimales (base 16), todos los números utilizados están en decimal (base 10). Cuando sea necesario expresar un número en hexadecimal, se utiliza el formato estándar de ensamblador de mainframe, que consiste en usar la letra mayúscula X antes del número, escribir las letras hexadecimales del número en mayúsculas y encerrar el número entre comillas simples; por ejemplo, el número 15deadbeef 16 se expresaría como X'15DEADBEEF'.

En este artículo, un "byte" equivale a 8 bits y, salvo que se especifique lo contrario, un "byte" y un "carácter" son sinónimos; los caracteres en EBCDIC también son de 8 bits. Cuando se utilizan conjuntos de caracteres multibyte (como Unicode ) en programas de usuario, estos emplean dos (o más) bytes.

Requisitos y restricciones

El formato es similar al formato de archivo de objeto de OS/360, pero agrega información adicional para su uso en la creación de aplicaciones. [ 4 ]

  • Los archivos GOFF son registros de longitud fija o variable.
  • Un registro GOFF debe caber completamente dentro de un único registro del sistema de archivos subyacente . Un archivo GOFF no es un archivo de tipo flujo .
  • Los registros de longitud fija deben tener un tamaño mínimo de 80 bytes. El tamaño mínimo de un registro de longitud variable es de 56 bytes. En el caso de los registros de longitud fija, habrá bytes sin usar al final del registro. Estos bytes deben establecerse a cero binario.
  • El programa que lee (o escribe) registros GOFF no debe hacer suposiciones sobre el formato interno de los registros; se presume que el sistema operativo puede proporcionar registros de longitud fija o variable sin que el programa que los lee necesite conocer la gestión interna de archivos del sistema operativo. La longitud de un registro no forma parte del registro en sí.
  • Los valores binarios se almacenan en formato big-endian ; por ejemplo, el valor 1 es X'01' para un valor de 8 bits, X'0001' para un valor de 16 bits, X'00000001' para un valor de 32 bits y X'0000000000000001' para un valor de 64 bits.
  • Los bits se cuentan de izquierda a derecha; el bit 0 es el bit situado más a la izquierda en un byte o palabra.
  • Los archivos GOFF implementados en sistemas Unix requieren registros de longitud fija .
  • Un registro puede continuarse en un registro posterior. Cuando se continúa un registro, no debe haber registros intermedios entre el registro que se continúa y el registro que lo continúa.
  • Un archivo de objeto GOFF comienza con un registro HDR y termina con un registro END. El registro END debe incluir la cantidad de registros GOFF (no la cantidad de registros físicos) en el archivo.
  • Un compilador o ensamblador de lenguaje puede generar varios archivos GOFF en una sola compilación/ensamblaje, pero estos archivos deben estar separados entre sí. Esto significa que un módulo o unidad de compilación, que consta de un registro HDR, ESD, TXT y otros, y que finaliza con un registro END, puede ir seguido de otra unidad de compilación que comience con HDR y termine con END, y así sucesivamente, según sea necesario.
  • Los nombres de módulos y clases distinguen entre mayúsculas y minúsculas. Un módulo llamado "exit" (como se usa en el lenguaje C ) no tiene por qué ser igual que "EXIT" (usado en el lenguaje Fortran ).
  • Algunas convenciones aplicables al formato de archivo de objeto de OS/360 se trasladan al formato de archivo de objeto GOFF, entre ellas:
    • Salvo que se especifique lo contrario, todos los caracteres pertenecen al conjunto de caracteres EBCDIC , excepto los nombres externos, como se indica a continuación.
    • Los elementos ESD (programas principales, subrutinas, funciones, FORTRAN Common, métodos y propiedades en objetos) deben numerarse comenzando por el 1, y cada nuevo elemento debe tener el siguiente número en la secuencia, sin ningún "hueco" en la numeración.
    • Un elemento ESD debe definirse antes de que cualquier otro registro (como un registro TXT o RLD) haga referencia a él.
    • Cada registro ESD contiene exactamente un elemento ESD. (Esto difiere del formato anterior, que permitía hasta 3 elementos ESD en cada registro ESD).
    • Un registro RLD (diccionario de reubicación [ 5 ] ) puede contener uno o más elementos, y un registro RLD puede continuar en un registro posterior.
    • Para garantizar la compatibilidad futura, los campos indicados como "reservados" deben establecerse en cero binario.
    • Los conjuntos de caracteres utilizados para nombres externos no están definidos por el estándar GOFF, pero existe una opción para especificar en un archivo qué conjunto de caracteres se está utilizando. (Esto permite admitir nombres de módulos basados ​​en Unicode con conjuntos de caracteres de doble byte ). Sin embargo, algunos productos de IBM solo permiten caracteres para nombres externos y otros identificadores dentro de un rango restringido, generalmente valores hexadecimales (EBCDIC) de X'41' a X'FE', más los caracteres de desplazamiento de entrada y salida, X'0F' y X'0E', respectivamente.
  • El nuevo formato admite nombres de clase, de los cuales existen dos tipos: reservados y proporcionados por el usuario o no reservados . Todos los nombres de clase tienen una longitud máxima de 16 caracteres.
  • Los nombres de clase reservados constan de una sola letra, un guion bajo y de 1 a 14 caracteres. Los nombres de clase reservados que comienzan con B_ están reservados para el encapsulador; los nombres de clase reservados que comienzan con C_ y están marcados como cargables están reservados para programas creados para su uso con el Entorno de Lenguaje (LE) de IBM. Los nombres de clase que comienzan con C_ que no están marcados como cargables, así como las clases que comienzan con X_, Y_ o Z_, están disponibles para uso general como no reservados .
  • Los nombres de clase proporcionados por el usuario pueden estar en minúsculas.
  • Los nombres de las clases no son símbolos externos.
  • Los manuales de IBM no mencionan qué página de códigos utiliza este formato, pero para los fines de este artículo asumiremos que es la 037, aunque eso no debería afectar a las instrucciones de la máquina ni a los datos almacenados por este formato.
Las siguientes clases utilizadas por el enlazador pueden consultarse si es necesario para fines de compilación:
Los siguientes nombres de clase están reservados por el enlazador y no son accesibles para las aplicaciones de usuario:
  • La información de la tabla simbólica del archivo de objeto SYM del registro de formato de archivo de objeto 360 no está disponible para los archivos de objeto GOFF; en su lugar, debe utilizarse el registro ADATA (subregistro de TXT).

Límite de tamaño

Según la Guía del usuario de z/OS XL C/C++, "El tamaño máximo de un objeto GOFF es de 1 gigabyte". [ 6 ]

Tipos de registros

De forma similar al formato anterior de OS/360, los registros de archivos de objetos se dividen en 6 tipos de registros diferentes, algunos añadidos, otros eliminados, otros modificados:

  • La grabación HDR (esto es nuevo) debe realizarse primero, ya que define el encabezado del archivo objeto.
  • Los registros ESD definen programas principales, subrutinas, funciones, secciones ficticias, Fortran Common, métodos y propiedades, así como cualquier módulo o rutina que pueda ser llamado por otro módulo. Se utilizan para definir el o los programas o segmentos de programa que se compilaron en esta ejecución del compilador, y las rutinas externas utilizadas por el programa (como exit() en C , CALL EXIT en Fortran ; new() y dispose() en Pascal ). Los registros ESD deben aparecer antes de cualquier referencia a un símbolo ESD.
  • Los registros TXT se han ampliado y, además de contener las instrucciones de la máquina o los datos que almacena el módulo, también contienen registros de datos de identificación (IDR) (20 o más tipos), registros de datos asociados (ADATA) e información adicional relacionada con el módulo.
  • Los registros RLD se utilizan para reubicar direcciones. Por ejemplo, un programa que hace referencia a una dirección ubicada 500 bytes dentro del módulo, almacenará internamente la dirección como 500, pero cuando el módulo se carga en la memoria, inevitablemente se ubicará en otro lugar. Por lo tanto, un registro RLD informa al editor de enlaces o al cargador qué direcciones debe modificar. Asimismo, cuando un módulo hace referencia a un símbolo externo, generalmente establece el valor de dicho símbolo en cero y luego incluye una entrada RLD para ese símbolo, lo que permite al cargador o al editor de enlaces modificar la dirección al valor correcto.
  • Los registros LEN son nuevos y proporcionan cierta información sobre la longitud.
  • Los registros END indican el final de un módulo y, opcionalmente, dónde debe comenzar la ejecución del programa. Este debe ser el último registro del archivo.

Formato

Los registros GOFF pueden ser de longitud fija o variable; la longitud mínima al usar registros de longitud variable es de 56 caracteres, aunque la mayoría de los registros serán más largos. Excepto los nombres de módulos y clases, todos los caracteres pertenecen al conjunto de caracteres EBCDIC . Los sistemas basados ​​en Unix deben usar registros de longitud fija (80 bytes). Los registros en archivos de longitud fija que sean más cortos que la longitud fija deben rellenarse con ceros. Para distinguir los registros GOFF del formato de objeto OS/360 anterior (donde el primer byte de un registro es X'02') o de los comandos que puedan estar presentes en el archivo, el primer byte de cada registro GOFF siempre es el valor binario X'03', mientras que los comandos deben comenzar con un valor de carácter de al menos un espacio (X'40'). Los siguientes 2 bytes de un registro GOFF indican el tipo de registro, la continuación y la versión del formato de archivo. Estos primeros 3 bytes se conocen como el campo PTV .

televisión de pago

El campo PTV representa los primeros 3 bytes de cada registro GOFF.

HDR

Se requiere el registro HDR, y debe ser el primer registro.

ESD

Un registro ESD proporciona el nombre público de un módulo, un programa principal, una subrutina, un procedimiento, una función, una propiedad o un método en un objeto, Fortran Common o un punto de entrada alternativo. Es necesario que exista un registro ESD para un nombre público en el archivo antes de que cualquier otro registro haga referencia a dicho nombre.

Continuación

En el caso de registros de longitud fija donde el nombre requiere registros de continuación, se utiliza lo siguiente:

Atributos de comportamiento

Registros ADATA

Los registros ADATA ("datos asociados") se utilizan para proporcionar información adicional sobre los símbolos de un módulo. Reemplazaron a los antiguos registros SYM en el formato de archivo de objeto 360. Para crear un registro ADATA

  • Cree un registro ESD de tipo ED para el nombre de la clase a la que pertenecen los registros.
  • Establezca todos los campos en el registro de Atributos de comportamiento en 0 excepto
    • La carga de clases (bits 0-1 del byte 5) es X'10'.
    • El algoritmo de enlace es 0
    • El estilo de registro de texto (bits 0-3 del byte 2) es X'0010'.
    • Opcionalmente, configure los valores de Solo lectura (bit 4 del byte 3) y No ejecutable (bits 5-7 del byte 3) si corresponde.
  • Cree un registro TXT para cada elemento ADATA.
    • El elemento ESDID es el valor del registro ADATA ED para esa entrada ADATA en particular.
    • El desplazamiento es cero
    • La longitud de los datos es la longitud del registro ADATA.
    • El campo de datos contiene el registro ADATA propiamente dicho.

Los registros ADATA se añadirán al final de la clase en el orden en que se declaren.

Los nombres de clase asignados a los registros ADATA son traducidos por los programas de IBM convirtiendo el valor binario a texto y agregándolo al nombre C_ADATA . Así, un elemento numerado X'0033' se convertiría en la cadena de texto C_ADATA0033 .

TXT

Los registros TXT especifican las instrucciones y los datos del código máquina que se colocarán en una dirección específica del módulo. Tenga en cuenta que, cuando se deba especificar una "longitud" para este registro, dicha longitud debe incluir cualquier continuación del mismo.

Precaución

La longitud de los datos en los bytes 22-23, al ser un valor sin signo, puede ser incorrecta. Según los comentarios en la parte del generador GOFF del conjunto de compiladores LLVM ,

"El número máximo de bytes que se pueden incluir en un registro RLD o TXT y sus continuaciones es un entero con signo de 16 bits, a pesar de lo que indique la especificación. Por lo tanto, el número de bytes que nos permitimos adjuntar a una tarjeta está limitado arbitrariamente a 32K-1 bytes." [ 7 ]

Continuación

Tabla de compresión

Se utiliza una tabla de compresión si los bytes 20-21 del registro TXT no son cero. El valor R se usa para determinar cuántas veces se repite la cadena; el valor L indica la longitud del texto que se repetirá "R" veces. Esto podría usarse para preinicializar tablas o matrices con espacios en blanco o cero, o para cualquier otro propósito donde sea útil expresar datos repetidos como un recuento de repeticiones y un valor.

Tabla de datos IDR

La tabla IDR, que se encuentra a partir del byte 24 del registro TXT, identifica el compilador o ensamblador (y su número de versión) que creó este archivo objeto.

Formato IDR 1

Tenga en cuenta que, a diferencia de la mayoría de los valores numéricos almacenados en un archivo GOFF, los valores "version", "release" y "trans_date" son números representados como caracteres de texto en lugar de binarios.

Formato IDR 2

Normalmente, los compiladores y ensambladores no generan este registro de formato; suele ser creado por el enlazador.

Formato IDR 3

Todo el texto de este elemento son datos de caracteres; no se utiliza información binaria.

RLD

Los registros RLD permiten que un módulo muestre dónde hace referencia a una dirección que debe reubicarse, como referencias a ubicaciones específicas dentro del propio módulo o a módulos externos.

Datos de reubicación

[A] Si se omiteR_Pointer (el bit 0 del byte 0 del campo Flags es 1), este campo comienza 4 bytes más abajo, en los bytes 8-11. [B] Si se omiteR_Pointer o P_Pointer (el bit 1 del byte 0 del campo Flags es 1), este campo comienza 4 bytes más abajo, en los bytes 12-15. Si se omiten ambos campos, este campo comienza 8 bytes más abajo, en los bytes 8-11. [C] Si se omiten R_Pointer, P_Pointer o Offset (el bit 2 del byte 0 del campo Flags es 1), este campo comienza 4 bytes más abajo. Si se omiten dos de ellos, este campo comienza 8 bytes más abajo. Si se omiten todos ellos, este campo comienza 12 bytes más abajo.

Para mayor claridad, si un módulo de un programa en C llamado "Basura" llamara a la función "exit" para finalizar, la dirección del puntero R sería el ESDID de la rutina "exit", mientras que el puntero P sería el ESDID de "Basura". Si la dirección se encuentra dentro del mismo módulo (como en el caso de subrutinas internas o referencias a datos dentro del mismo módulo), los punteros R y P serían iguales.

Banderas

LEN

Los registros LEN se utilizan para declarar la longitud de un módulo cuando esta se desconocía en el momento de la creación del registro ESD, por ejemplo, para compiladores de una sola pasada.

Elementos

Una entrada de elemento de longitud diferida no se puede continuar ni dividir.

FIN

END debe ser el último registro de un módulo. Se utiliza un "Punto de Entrada" cuando se va a usar una dirección distinta al inicio del módulo como punto de inicio de su ejecución. Esto puede ocurrir porque el programa contiene datos no ejecutables antes del inicio del módulo (algo muy común entre los programadores de lenguaje ensamblador más antiguos, ya que las versiones anteriores del ensamblador eran mucho más lentas para ensamblar los datos almacenados en los programas una vez especificadas las instrucciones).

Continuación

Si el nombre de un punto de entrada especificado en un registro END de longitud fija es más largo que 54 bytes o (si este registro también tiene continuación) es más largo que 77 bytes adicionales), se utiliza el siguiente registro de continuación.

Notas

  1. Este uso difiere del de IBM, donde un módulo objeto (unidad de compilación) puede contener múltiples subrutinas, etc., y un módulo de carga puede contener subrutinas, etc., de múltiples módulos objeto.

Referencias

  1. John R. Ehrman (1 de marzo de 2001). "Cómo funciona el editor de enlaces: un tutorial sobre módulos de objetos/carga, editores de enlaces, cargadores y lo que hacen por (y para) usted" (PDF) . Servidor FTP ( FTP ). Laboratorio IBM Silicon Valley (Santa Teresa), San José . Recuperado el 8 de septiembre de 2019 .(Para ver los documentos, consulte Ayuda:FTP )
  2. "Apéndice C. Formato de archivo de objeto generalizado (GOFF)" (PDF) . MVS Program Management: Advanced Facilities (PDF) . z/OS (octava ed.). Poughkeepsie, NY: IBM . Septiembre de 2007. págs. 205–240 . SA22-7644-07. Archivado del original (PDF) el 19 de octubre de 2021. Recuperado el 9 de agosto de 2013 .  
  3. Guía de presentación de IBM High Level Assembler para MVS, VM y VSE versión 2 (PDF) . Diciembre de 1995. SG24-3910-01. Archivado del original (PDF) el 23 de enero de 2016. Consultado el 13 de noviembre de 2015 .
  4. Guía del programador de High Level Assembler para z/OS, z/VM y z/VSE (PDF) (sexta edición). San José, CA: IBM. Julio de 2008. Apéndice C. SC26-4941-05 . Consultado el 8 de septiembre de 2019 . 
  5. "RLD" . www.ibm.com . IBM. 16 de agosto de 2013. Consultado el 10 de julio de 2020 .
  6. "Lp64 | Ilp32" . IBM .
  7. "llvm/BinaryFormat/GOFF.h - Definiciones GOFF" . LLVM.ORG . Consultado el 16 de agosto de 2024 .