Although many assemblers provide powerful macro languages and other high level language features, assembler languages almost always reflect the machine architecture, the object code format and the constraints of the linker. This is the case for the Tachyon z/Assembler. Because the ELF object file format and the Linux linker are different than the traditional mainframe formats and linkers, when the Tachyon z/Assembler produces an ELF file, the assembler language must be changed to reflect ELF concepts. Anyone programming in assembler for an ELF target must be aware of these concepts.
More information about ELF and Linux for S/390 and zSeries can be found at http://www.tachyonsoft.com/elf.html.
In both ELF and traditional mainframe object files, data areas and instructions are grouped into sections. Sections can have named locations within them and these names can be made visible to the linker. Location names that are visible to the linker are often called entry point names or external symbols.
Traditional IBM mainframe assembler programs are divided into sections that are linked together. Normally, code and data are not placed in separate sections. Section names have no particular meaning. Section names are also entry point names and can be referenced by other sections. If two sections are named identically, the linker normally discards all but the first section.
In ELF files, sections are concatenated. When the Linux linker finds two or more sections with the same name, it creates an area in the resulting executable program file that is a combination of the sections. In ELF, only a few section names are normally used. All section names begin with a dot:
SectionName | Usage | Attributes |
---|---|---|
.text | Executable instructions and the literal pool. | Read-only |
.rodata | Constant data areas. | Read-only |
.data | Initialized data areas. | Read/Write |
.bss | Uninitialized (common) data areas. | Read/Write |
Normally, an ELF program will consist of one or more blocks of code (functions) in the .text section, some initialized data areas in the .data section and perhaps some read-only constants in .rodata and some uninitialized common data areas.
Any or all of the above sections may be defined in the assembler source. The linker creates the final .bss section as a concatenation of the common storage areas and any explict .bss sections. Common areas with the same name are combined by the linker and all .bss storage is initialized to zero when the program is loaded.
The attributes of each section name are fixed. Modifiable data areas cannot be placed in the .text or .rodata sections without potentially causing an execution fault. The assembler and the linker sort the sections in the sequence they appear in the table above.
In ELF, section names are not external symbols. All entry point names must be explicitly defined. In ELF, entry points are not only associated with a location, they can also have attributes. They can be declared to be associated with code or data. They can have a length, thus defining an area of storage. They can also be defined as local, weak or global. Local names are ignored by the linker. Global and weak names can be used to resolve external references.
Like the traditional object file formats, external references can be defined in ELF files as weak. Normal external references will cause the linker to perform a library search. Weak external references will only be resolved if a global entry point of the same name is found in an object module read by the linker.