fis-gtm/sr_unix_nsb/obj_code.c

196 lines
5.1 KiB
C

/****************************************************************
* *
* Copyright 2001, 2010 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_fcntl.h"
#include "gtm_stdio.h"
#include <errno.h>
#include "gtm_stat.h"
#include <sys/types.h>
#include "gtm_unistd.h"
#include "compiler.h"
#include "obj_gen.h"
#include "rtnhdr.h"
#include "cmd_qlf.h"
#include "cgp.h"
#ifdef UNIX
#include "gtmio.h"
#include "eintr_wrappers.h"
#endif
#include "mmemory.h"
#include "obj_file.h"
#include "alloc_reg.h"
#include "jmp_opto.h"
#include "mlabel2xtern.h"
#include "cg_var.h"
#include "gtm_string.h"
#include "stringpool.h"
GBLREF boolean_t run_time;
GBLREF command_qualifier cmd_qlf;
GBLREF int4 mvmax, mlmax, mlitmax, psect_use_tab[], sa_temps[], sa_temps_offset[];
GBLREF mlabel *mlabtab;
GBLREF mline mline_root;
GBLREF mvar *mvartab;
GBLREF mident module_name, int_module_name;
GBLREF spdesc stringpool;
GBLREF char cg_phase; /* code generation phase */
GBLREF char cg_phase_last; /* previous code generation phase */
GBLREF int4 curr_addr, code_size;
void cg_lab (mlabel *l, int4 base);
/* The sections of the internal GT.M object are grouped according to their type (R/O, R/W).
* Note: Once an object is linked, no section will be released from memory. All sections
* will be retained.
*
* The GT.M object layout on the disk is as follows:
*
* +---------------+
* | rhead | \
* +---------------+ \
* | generated | |
* | code | |
* + - - - - - - - + |
* | variable tbl | | - R/O
* + - - - - - - - + |
* | label tbl | |
* +---------------+ |
* | line num tbl | |
* + - - - - - - - + /
* | lit text pool | /
* +---------------+
* | lit mval tbl |-- R/W
* +---------------+
* | relocations | > - relocations for external syms (not kept after link)
* +---------------+
* | symbol tbl | > - external symbol table (not kept after link)
* +---------------+
*
*/
void obj_code (uint4 src_lines, uint4 checksum)
{
rhdtyp rhead;
mline *mlx, *mly;
var_tabent *vptr;
int4 lnr_pad_len;
error_def(ERR_TEXT);
assert(!run_time);
obj_init();
/* Define the routine name global symbol. */
define_symbol(GTM_MODULE_DEF_PSECT, (mstr *)&int_module_name, 0);
memset(&rhead, 0, SIZEOF(rhead));
alloc_reg();
jmp_opto();
curr_addr = SIZEOF(rhdtyp);
cg_phase = CGP_APPROX_ADDR;
cg_phase_last = CGP_NOSTATE;
code_gen();
code_size = curr_addr;
cg_phase = CGP_ADDR_OPT;
shrink_jmps();
comp_lits(&rhead);
if ((cmd_qlf.qlf & CQ_MACHINE_CODE))
{
cg_phase = CGP_ASSEMBLY;
code_gen();
}
if (!(cmd_qlf.qlf & CQ_OBJECT))
return;
rhead.ptext_ptr = SIZEOF(rhead);
rhead.checksum = checksum;
rhead.vartab_ptr = code_size;
rhead.vartab_len = mvmax;
code_size += mvmax * SIZEOF(var_tabent);
rhead.labtab_ptr = code_size;
rhead.labtab_len = mlmax;
code_size += mlmax * SIZEOF(lab_tabent);
rhead.lnrtab_ptr = code_size;
rhead.lnrtab_len = src_lines;
rhead.compiler_qlf = cmd_qlf.qlf;
rhead.temp_mvals = sa_temps[TVAL_REF];
rhead.temp_size = sa_temps_offset[TCAD_REF];
code_size += src_lines * SIZEOF(int4);
lnr_pad_len = PADLEN(code_size, SECTION_ALIGN_BOUNDARY);
code_size += lnr_pad_len;
create_object_file(&rhead);
cg_phase = CGP_MACHINE;
code_gen();
/* Variable table: */
vptr = (var_tabent *)mcalloc(mvmax * SIZEOF(var_tabent));
if (mvartab)
walktree(mvartab, cg_var, (char *)&vptr);
else
assert(0 == mvmax);
emit_immed((char *)vptr, mvmax * SIZEOF(var_tabent));
/* Label table: */
if (mlabtab)
walktree((mvar *)mlabtab, cg_lab, (char *)rhead.lnrtab_ptr);
else
assert(0 == mlmax);
/* External entry definitions: */
emit_immed((char *)&(mline_root.externalentry->rtaddr), SIZEOF(mline_root.externalentry->rtaddr)); /* line 0 */
for (mlx = mline_root.child ; mlx ; mlx = mly)
{
if (mlx->table)
emit_immed((char *)&(mlx->externalentry->rtaddr), SIZEOF(mlx->externalentry->rtaddr));
if ((mly = mlx->child) == 0)
{
if ((mly = mlx->sibling) == 0)
{
for (mly = mlx; ; )
{
if ((mly = mly->parent) == 0)
break;
if (mly->sibling)
{
mly = mly->sibling;
break;
}
}
}
}
}
if (0 != lnr_pad_len) /* emit padding so literal text pool starts on proper boundary */
emit_immed(PADCHARS, lnr_pad_len);
#if !defined(__MVS__) && !defined(__s390__) /* assert not valid for instructions on OS390 */
assert (code_size == psect_use_tab[GTM_CODE]);
#endif
emit_literals();
close_object_file();
}
void cg_lab (mlabel *l, int4 base)
{
mstr glob_name;
lab_tabent lent;
if (l->ml && l->gbl)
{
lent.lab_name.len = l->mvname.len;
lent.lab_name.addr = (char *)(l->mvname.addr - (char *)stringpool.base);
lent.LABENT_LNR_OFFSET = (SIZEOF(lnr_tabent) * l->ml->line_number) + base;
emit_immed((char *)&lent, SIZEOF(lent));
mlabel2xtern(&glob_name, &int_module_name, &l->mvname);
define_symbol(GTM_CODE, &glob_name, lent.LABENT_LNR_OFFSET);
}
}