Revamp object format functional interface a bit. Now, only the output()

function gets a FILE *, and it's the only function that can write to a file.
The object file is thus not opened until AFTER parsing and most error checking
is complete.  Necessitated adding a special case for the dbg object format
because it needs to output to the "object" (debug) file from essentially every
function.  Added a global (debug_file) to support this.

svn path=/trunk/yasm/; revision=476
0.3
Peter Johnson 23 years ago
parent a0d61f00c1
commit 0177d689a1
  1. 123
      frontends/yasm/yasm.c
  2. 8
      libyasm/linemgr.c
  3. 8
      libyasm/linemgr.h
  4. 15
      libyasm/objfmt.h
  5. 118
      modules/objfmts/dbg/dbg-objfmt.c
  6. 8
      src/globals.c
  7. 8
      src/globals.h
  8. 8
      src/linemgr.c
  9. 8
      src/linemgr.h
  10. 123
      src/main.c
  11. 15
      src/objfmt.h
  12. 118
      src/objfmts/dbg/dbg-objfmt.c

@ -51,6 +51,9 @@ static int files_open = 0;
/*@null@*/ static FILE *in = NULL, *obj = NULL;
static int special_options = 0;
static int open_obj(void);
static void cleanup(sectionhead *sections);
/* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
@ -154,12 +157,10 @@ main(int argc, char *argv[])
/* Set x86 as the architecture */
cur_arch = &x86_arch;
/* Set dbg as the object format */
cur_objfmt = find_objfmt("dbg");
if (!cur_objfmt) {
ErrorNow(_("unrecognized output format `%s'"), "dbg");
return EXIT_FAILURE;
}
/* If not already specified, default to dbg as the object format. */
if (!cur_objfmt)
cur_objfmt = find_objfmt("dbg");
assert(cur_objfmt != NULL);
/* open the object file if not specified */
if (!obj) {
@ -170,17 +171,19 @@ main(int argc, char *argv[])
/* replace (or add) extension */
obj_filename = replace_extension(in_filename, cur_objfmt->extension,
"yasm.out");
}
/* open the built filename */
obj = fopen(obj_filename, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), obj_filename);
/* Pre-open the object file as debug_file if we're using a debug-type
* format. (This is so the format can output ALL function call info).
*/
if (strcmp(cur_objfmt->keyword, "dbg") == 0) {
if (!open_obj())
return EXIT_FAILURE;
}
debug_file = obj;
}
/* Initialize the object format */
cur_objfmt->initialize(obj);
cur_objfmt->initialize(in_filename, obj_filename);
/* Set NASM as the parser */
cur_parser = find_parser("nasm");
@ -200,53 +203,69 @@ main(int argc, char *argv[])
xfree(in_filename);
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
line_shutdown();
floatnum_shutdown();
intnum_shutdown();
BitVector_Shutdown();
cleanup(sections);
return EXIT_FAILURE;
}
/* XXX Only for temporary debugging! */
fprintf(obj, "\nSections after parsing:\n");
indent_level++;
sections_print(obj, sections);
indent_level--;
fprintf(obj, "\nSymbol Table:\n");
indent_level++;
symrec_print_all(obj);
indent_level--;
symrec_parser_finalize();
basic_optimizer.optimize(sections);
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
line_shutdown();
floatnum_shutdown();
intnum_shutdown();
BitVector_Shutdown();
cleanup(sections);
return EXIT_FAILURE;
}
fprintf(obj, "\nSections after optimization:\n");
indent_level++;
sections_print(obj, sections);
indent_level--;
/* open the object file for output (if not already opened above) */
if (!debug_file) {
if (!open_obj())
return EXIT_FAILURE;
}
/* Write the object file */
cur_objfmt->output(obj, sections);
/* Finalize the object output */
cur_objfmt->finalize();
cur_objfmt->cleanup();
if (obj != stdout)
fclose(obj);
/* If we had an error at this point, we also need to delete the output
* object file (to make sure it's not left newer than the source).
*/
if (OutputAllErrorWarning() > 0) {
cleanup(sections);
if (obj != stdout)
remove(obj_filename);
return EXIT_FAILURE;
}
if (obj_filename)
xfree(obj_filename);
cleanup(sections);
return EXIT_SUCCESS;
}
/*@=globstate =unrecog@*/
/* Open the object file. Returns 0 on failure. */
static int
open_obj(void)
{
if (obj != stdout) {
obj = fopen(obj_filename, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), obj_filename);
return 0;
}
}
return 1;
}
/* Cleans up all allocated structures. */
static void
cleanup(sectionhead *sections)
{
sections_delete(sections);
symrec_delete_all();
line_shutdown();
@ -255,9 +274,7 @@ main(int argc, char *argv[])
intnum_shutdown();
BitVector_Shutdown();
return EXIT_SUCCESS;
}
/*@=globstate =unrecog@*/
/*
* Command line options handlers
@ -296,7 +313,11 @@ static int
opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
{
assert(param != NULL);
printf("selected format: %s\n", param);
cur_objfmt = find_objfmt(param);
if (!cur_objfmt) {
ErrorNow(_("unrecognized object format `%s'"), param);
return 1;
}
return 0;
}
@ -305,22 +326,22 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
/*@unused@*/ int extra)
{
assert(param != NULL);
if (strcasecmp(param, "stdout") == 0)
if (strcmp(param, "-") == 0)
obj = stdout;
else if (strcasecmp(param, "stderr") == 0)
obj = stderr;
else {
if (obj) {
WarningNow("can open only one output file, last specified used");
if (obj != stdout && obj != stderr && fclose(obj))
if (obj != stdout && fclose(obj))
ErrorNow("could not close old output file");
}
}
obj = fopen(param, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), param);
return 1;
if (obj != stdout) {
obj = fopen(param, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), param);
return 1;
}
}
if (obj_filename)

@ -27,6 +27,14 @@
#include "globals.h"
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
/*@null@*/ FILE *debug_file = NULL;
/* Current (selected) parser */
/*@null@*/ parser *cur_parser = NULL;

@ -22,6 +22,14 @@
#ifndef YASM_GLOBALS_H
#define YASM_GLOBALS_H
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
extern /*@null@*/ FILE *debug_file;
/* Current (selected) parser */
extern /*@null@*/ parser *cur_parser;

@ -50,12 +50,19 @@ struct objfmt {
/* debugfmt *default_df;*/
/* Initializes object output. Must be called before any other object
* format functions.
* format functions. Should NOT open the object file; the filenames are
* provided solely for informational purposes.
*/
void (*initialize) (/*@dependent@*/ FILE *f);
void (*initialize) (const char *in_filename, const char *obj_filename);
/* Finishes object output, and cleans up anything created by initialize. */
void (*finalize) (void);
/* Write out (post-optimized) sections to the object file.
* This function may call symrec functions as necessary (including
* symrec_traverse) to retrieve symbolic information.
*/
void (*output) (FILE *f, sectionhead *sections);
/* Cleans up anything allocated by initialize. */
void (*cleanup) (void);
/* Switch object file sections. The first val of the valparams should
* be the section name. Returns NULL if something's wrong, otherwise

@ -31,19 +31,36 @@
#include "objfmt.h"
/*@dependent@*/ FILE *dbg_f;
/* Note that the functions here write to debug_file. This is NOT legal for
* other object formats to do--only the output() function can write to a file,
* and only the file it's passed in its f parameter!
*/
static void
dbg_objfmt_initialize(const char *in_filename, const char *obj_filename)
{
fprintf(debug_file, "%*sinitialize(\"%s\", \"%s\")\n", indent_level, "",
in_filename, obj_filename);
}
static void
dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
dbg_objfmt_output(FILE *f, sectionhead *sections)
{
dbg_f = f;
fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
fprintf(f, "%*soutput(f, sections->\n", indent_level, "");
indent_level++;
sections_print(f, sections);
indent_level--;
fprintf(f, "%*s)\n", indent_level, "");
indent_level++;
fprintf(f, "%*sSymbol Table:\n", indent_level, "");
symrec_print_all(f);
indent_level--;
}
static void
dbg_objfmt_finalize(void)
dbg_objfmt_cleanup(void)
{
fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
fprintf(debug_file, "%*scleanup()\n", indent_level, "");
}
static /*@dependent@*/ /*@null@*/ section *
@ -55,22 +72,22 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
section *retval;
int isnew;
fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
vps_print(dbg_f, valparams);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning ");
fprintf(debug_file, "%*ssections_switch(headp, ", indent_level, "");
vps_print(debug_file, valparams);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning ");
if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
if (isnew) {
fprintf(dbg_f, "(new) ");
fprintf(debug_file, "(new) ");
symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
}
fprintf(dbg_f, "\"%s\" section\n", vp->val);
fprintf(debug_file, "\"%s\" section\n", vp->val);
return retval;
} else {
fprintf(dbg_f, "NULL\n");
fprintf(debug_file, "NULL\n");
return NULL;
}
}
@ -78,7 +95,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
static void
dbg_objfmt_section_data_delete(/*@only@*/ void *data)
{
fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
fprintf(debug_file, "%*ssection_data_delete(%p)\n", indent_level, "", data);
xfree(data);
}
@ -95,9 +112,9 @@ static /*@null@*/ void *
dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning NULL\n");
fprintf(debug_file, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning NULL\n");
return NULL;
}
@ -105,9 +122,9 @@ static /*@null@*/ void *
dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning NULL\n");
fprintf(debug_file, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning NULL\n");
return NULL;
}
@ -116,13 +133,13 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
/*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
expr_print(dbg_f, size);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning ");
expr_print(dbg_f, size);
fprintf(dbg_f, "\n");
fprintf(debug_file, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
expr_print(debug_file, size);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning ");
expr_print(debug_file, size);
fprintf(debug_file, "\n");
return size;
}
@ -131,29 +148,29 @@ dbg_objfmt_declare_data_copy(SymVisibility vis, /*@only@*/ void *data)
{
void *retval;
fprintf(dbg_f, "%*sdeclare_data_copy(", indent_level, "");
fprintf(debug_file, "%*sdeclare_data_copy(", indent_level, "");
switch (vis) {
case SYM_LOCAL:
fprintf(dbg_f, "Local, ");
fprintf(debug_file, "Local, ");
break;
case SYM_GLOBAL:
fprintf(dbg_f, "Global, ");
fprintf(debug_file, "Global, ");
break;
case SYM_COMMON:
fprintf(dbg_f, "Common, ");
fprintf(debug_file, "Common, ");
break;
case SYM_EXTERN:
fprintf(dbg_f, "Extern, ");
fprintf(debug_file, "Extern, ");
break;
}
if (vis == SYM_COMMON) {
expr_print(dbg_f, data);
expr_print(debug_file, data);
retval = expr_copy(data);
} else {
fprintf(dbg_f, "%p", data);
fprintf(debug_file, "%p", data);
InternalError(_("Trying to copy unrecognized objfmt data"));
}
fprintf(dbg_f, "), returning copy\n");
fprintf(debug_file, "), returning copy\n");
return retval;
}
@ -161,29 +178,29 @@ dbg_objfmt_declare_data_copy(SymVisibility vis, /*@only@*/ void *data)
static void
dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
{
fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
fprintf(debug_file, "%*sdeclare_data_delete(", indent_level, "");
switch (vis) {
case SYM_LOCAL:
fprintf(dbg_f, "Local, ");
fprintf(debug_file, "Local, ");
break;
case SYM_GLOBAL:
fprintf(dbg_f, "Global, ");
fprintf(debug_file, "Global, ");
break;
case SYM_COMMON:
fprintf(dbg_f, "Common, ");
fprintf(debug_file, "Common, ");
break;
case SYM_EXTERN:
fprintf(dbg_f, "Extern, ");
fprintf(debug_file, "Extern, ");
break;
}
if (vis == SYM_COMMON) {
expr_print(dbg_f, data);
expr_print(debug_file, data);
expr_delete(data);
} else {
fprintf(dbg_f, "%p", data);
fprintf(debug_file, "%p", data);
xfree(data);
}
fprintf(dbg_f, ")\n");
fprintf(debug_file, ")\n");
}
static void
@ -203,11 +220,11 @@ static int
dbg_objfmt_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, valparams);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning 0 (recognized)\n");
fprintf(debug_file, "%*sdirective(\"%s\", ", indent_level, "", name);
vps_print(debug_file, valparams);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning 0 (recognized)\n");
return 0; /* dbg format "recognizes" all directives */
}
@ -219,7 +236,8 @@ objfmt dbg_objfmt = {
".text",
32,
dbg_objfmt_initialize,
dbg_objfmt_finalize,
dbg_objfmt_output,
dbg_objfmt_cleanup,
dbg_objfmt_sections_switch,
dbg_objfmt_section_data_delete,
dbg_objfmt_section_data_print,

@ -27,6 +27,14 @@
#include "globals.h"
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
/*@null@*/ FILE *debug_file = NULL;
/* Current (selected) parser */
/*@null@*/ parser *cur_parser = NULL;

@ -22,6 +22,14 @@
#ifndef YASM_GLOBALS_H
#define YASM_GLOBALS_H
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
extern /*@null@*/ FILE *debug_file;
/* Current (selected) parser */
extern /*@null@*/ parser *cur_parser;

@ -27,6 +27,14 @@
#include "globals.h"
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
/*@null@*/ FILE *debug_file = NULL;
/* Current (selected) parser */
/*@null@*/ parser *cur_parser = NULL;

@ -22,6 +22,14 @@
#ifndef YASM_GLOBALS_H
#define YASM_GLOBALS_H
/* Output file for debugging-type formats. This is so that functions that are
* called before the object file is usually opened can still write data out to
* it (whereas for "normal" formats the object file is not opened until later
* in the assembly process). Opening the file early is special-cased in
* main().
*/
extern /*@null@*/ FILE *debug_file;
/* Current (selected) parser */
extern /*@null@*/ parser *cur_parser;

@ -51,6 +51,9 @@ static int files_open = 0;
/*@null@*/ static FILE *in = NULL, *obj = NULL;
static int special_options = 0;
static int open_obj(void);
static void cleanup(sectionhead *sections);
/* Forward declarations: cmd line parser handlers */
static int opt_special_handler(char *cmd, /*@null@*/ char *param, int extra);
static int opt_format_handler(char *cmd, /*@null@*/ char *param, int extra);
@ -154,12 +157,10 @@ main(int argc, char *argv[])
/* Set x86 as the architecture */
cur_arch = &x86_arch;
/* Set dbg as the object format */
cur_objfmt = find_objfmt("dbg");
if (!cur_objfmt) {
ErrorNow(_("unrecognized output format `%s'"), "dbg");
return EXIT_FAILURE;
}
/* If not already specified, default to dbg as the object format. */
if (!cur_objfmt)
cur_objfmt = find_objfmt("dbg");
assert(cur_objfmt != NULL);
/* open the object file if not specified */
if (!obj) {
@ -170,17 +171,19 @@ main(int argc, char *argv[])
/* replace (or add) extension */
obj_filename = replace_extension(in_filename, cur_objfmt->extension,
"yasm.out");
}
/* open the built filename */
obj = fopen(obj_filename, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), obj_filename);
/* Pre-open the object file as debug_file if we're using a debug-type
* format. (This is so the format can output ALL function call info).
*/
if (strcmp(cur_objfmt->keyword, "dbg") == 0) {
if (!open_obj())
return EXIT_FAILURE;
}
debug_file = obj;
}
/* Initialize the object format */
cur_objfmt->initialize(obj);
cur_objfmt->initialize(in_filename, obj_filename);
/* Set NASM as the parser */
cur_parser = find_parser("nasm");
@ -200,53 +203,69 @@ main(int argc, char *argv[])
xfree(in_filename);
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
line_shutdown();
floatnum_shutdown();
intnum_shutdown();
BitVector_Shutdown();
cleanup(sections);
return EXIT_FAILURE;
}
/* XXX Only for temporary debugging! */
fprintf(obj, "\nSections after parsing:\n");
indent_level++;
sections_print(obj, sections);
indent_level--;
fprintf(obj, "\nSymbol Table:\n");
indent_level++;
symrec_print_all(obj);
indent_level--;
symrec_parser_finalize();
basic_optimizer.optimize(sections);
if (OutputAllErrorWarning() > 0) {
sections_delete(sections);
symrec_delete_all();
line_shutdown();
floatnum_shutdown();
intnum_shutdown();
BitVector_Shutdown();
cleanup(sections);
return EXIT_FAILURE;
}
fprintf(obj, "\nSections after optimization:\n");
indent_level++;
sections_print(obj, sections);
indent_level--;
/* open the object file for output (if not already opened above) */
if (!debug_file) {
if (!open_obj())
return EXIT_FAILURE;
}
/* Write the object file */
cur_objfmt->output(obj, sections);
/* Finalize the object output */
cur_objfmt->finalize();
cur_objfmt->cleanup();
if (obj != stdout)
fclose(obj);
/* If we had an error at this point, we also need to delete the output
* object file (to make sure it's not left newer than the source).
*/
if (OutputAllErrorWarning() > 0) {
cleanup(sections);
if (obj != stdout)
remove(obj_filename);
return EXIT_FAILURE;
}
if (obj_filename)
xfree(obj_filename);
cleanup(sections);
return EXIT_SUCCESS;
}
/*@=globstate =unrecog@*/
/* Open the object file. Returns 0 on failure. */
static int
open_obj(void)
{
if (obj != stdout) {
obj = fopen(obj_filename, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), obj_filename);
return 0;
}
}
return 1;
}
/* Cleans up all allocated structures. */
static void
cleanup(sectionhead *sections)
{
sections_delete(sections);
symrec_delete_all();
line_shutdown();
@ -255,9 +274,7 @@ main(int argc, char *argv[])
intnum_shutdown();
BitVector_Shutdown();
return EXIT_SUCCESS;
}
/*@=globstate =unrecog@*/
/*
* Command line options handlers
@ -296,7 +313,11 @@ static int
opt_format_handler(/*@unused@*/ char *cmd, char *param, /*@unused@*/ int extra)
{
assert(param != NULL);
printf("selected format: %s\n", param);
cur_objfmt = find_objfmt(param);
if (!cur_objfmt) {
ErrorNow(_("unrecognized object format `%s'"), param);
return 1;
}
return 0;
}
@ -305,22 +326,22 @@ opt_objfile_handler(/*@unused@*/ char *cmd, char *param,
/*@unused@*/ int extra)
{
assert(param != NULL);
if (strcasecmp(param, "stdout") == 0)
if (strcmp(param, "-") == 0)
obj = stdout;
else if (strcasecmp(param, "stderr") == 0)
obj = stderr;
else {
if (obj) {
WarningNow("can open only one output file, last specified used");
if (obj != stdout && obj != stderr && fclose(obj))
if (obj != stdout && fclose(obj))
ErrorNow("could not close old output file");
}
}
obj = fopen(param, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), param);
return 1;
if (obj != stdout) {
obj = fopen(param, "wb");
if (!obj) {
ErrorNow(_("could not open file `%s'"), param);
return 1;
}
}
if (obj_filename)

@ -50,12 +50,19 @@ struct objfmt {
/* debugfmt *default_df;*/
/* Initializes object output. Must be called before any other object
* format functions.
* format functions. Should NOT open the object file; the filenames are
* provided solely for informational purposes.
*/
void (*initialize) (/*@dependent@*/ FILE *f);
void (*initialize) (const char *in_filename, const char *obj_filename);
/* Finishes object output, and cleans up anything created by initialize. */
void (*finalize) (void);
/* Write out (post-optimized) sections to the object file.
* This function may call symrec functions as necessary (including
* symrec_traverse) to retrieve symbolic information.
*/
void (*output) (FILE *f, sectionhead *sections);
/* Cleans up anything allocated by initialize. */
void (*cleanup) (void);
/* Switch object file sections. The first val of the valparams should
* be the section name. Returns NULL if something's wrong, otherwise

@ -31,19 +31,36 @@
#include "objfmt.h"
/*@dependent@*/ FILE *dbg_f;
/* Note that the functions here write to debug_file. This is NOT legal for
* other object formats to do--only the output() function can write to a file,
* and only the file it's passed in its f parameter!
*/
static void
dbg_objfmt_initialize(const char *in_filename, const char *obj_filename)
{
fprintf(debug_file, "%*sinitialize(\"%s\", \"%s\")\n", indent_level, "",
in_filename, obj_filename);
}
static void
dbg_objfmt_initialize(/*@dependent@*/ FILE *f)
dbg_objfmt_output(FILE *f, sectionhead *sections)
{
dbg_f = f;
fprintf(dbg_f, "%*sinitialize(f)\n", indent_level, "");
fprintf(f, "%*soutput(f, sections->\n", indent_level, "");
indent_level++;
sections_print(f, sections);
indent_level--;
fprintf(f, "%*s)\n", indent_level, "");
indent_level++;
fprintf(f, "%*sSymbol Table:\n", indent_level, "");
symrec_print_all(f);
indent_level--;
}
static void
dbg_objfmt_finalize(void)
dbg_objfmt_cleanup(void)
{
fprintf(dbg_f, "%*sfinalize()\n", indent_level, "");
fprintf(debug_file, "%*scleanup()\n", indent_level, "");
}
static /*@dependent@*/ /*@null@*/ section *
@ -55,22 +72,22 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
section *retval;
int isnew;
fprintf(dbg_f, "%*ssections_switch(headp, ", indent_level, "");
vps_print(dbg_f, valparams);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning ");
fprintf(debug_file, "%*ssections_switch(headp, ", indent_level, "");
vps_print(debug_file, valparams);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning ");
if ((vp = vps_first(valparams)) && !vp->param && vp->val != NULL) {
retval = sections_switch_general(headp, vp->val, NULL, 0, &isnew);
if (isnew) {
fprintf(dbg_f, "(new) ");
fprintf(debug_file, "(new) ");
symrec_define_label(vp->val, retval, (bytecode *)NULL, 1);
}
fprintf(dbg_f, "\"%s\" section\n", vp->val);
fprintf(debug_file, "\"%s\" section\n", vp->val);
return retval;
} else {
fprintf(dbg_f, "NULL\n");
fprintf(debug_file, "NULL\n");
return NULL;
}
}
@ -78,7 +95,7 @@ dbg_objfmt_sections_switch(sectionhead *headp, valparamhead *valparams,
static void
dbg_objfmt_section_data_delete(/*@only@*/ void *data)
{
fprintf(dbg_f, "%*ssection_data_delete(%p)\n", indent_level, "", data);
fprintf(debug_file, "%*ssection_data_delete(%p)\n", indent_level, "", data);
xfree(data);
}
@ -95,9 +112,9 @@ static /*@null@*/ void *
dbg_objfmt_extern_data_new(const char *name, /*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning NULL\n");
fprintf(debug_file, "%*sextern_data_new(\"%s\", ", indent_level, "", name);
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning NULL\n");
return NULL;
}
@ -105,9 +122,9 @@ static /*@null@*/ void *
dbg_objfmt_global_data_new(const char *name, /*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning NULL\n");
fprintf(debug_file, "%*sglobal_data_new(\"%s\", ", indent_level, "", name);
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning NULL\n");
return NULL;
}
@ -116,13 +133,13 @@ dbg_objfmt_common_data_new(const char *name, /*@only@*/ expr *size,
/*@unused@*/ /*@null@*/
valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
expr_print(dbg_f, size);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning ");
expr_print(dbg_f, size);
fprintf(dbg_f, "\n");
fprintf(debug_file, "%*scommon_data_new(\"%s\", ", indent_level, "", name);
expr_print(debug_file, size);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning ");
expr_print(debug_file, size);
fprintf(debug_file, "\n");
return size;
}
@ -131,29 +148,29 @@ dbg_objfmt_declare_data_copy(SymVisibility vis, /*@only@*/ void *data)
{
void *retval;
fprintf(dbg_f, "%*sdeclare_data_copy(", indent_level, "");
fprintf(debug_file, "%*sdeclare_data_copy(", indent_level, "");
switch (vis) {
case SYM_LOCAL:
fprintf(dbg_f, "Local, ");
fprintf(debug_file, "Local, ");
break;
case SYM_GLOBAL:
fprintf(dbg_f, "Global, ");
fprintf(debug_file, "Global, ");
break;
case SYM_COMMON:
fprintf(dbg_f, "Common, ");
fprintf(debug_file, "Common, ");
break;
case SYM_EXTERN:
fprintf(dbg_f, "Extern, ");
fprintf(debug_file, "Extern, ");
break;
}
if (vis == SYM_COMMON) {
expr_print(dbg_f, data);
expr_print(debug_file, data);
retval = expr_copy(data);
} else {
fprintf(dbg_f, "%p", data);
fprintf(debug_file, "%p", data);
InternalError(_("Trying to copy unrecognized objfmt data"));
}
fprintf(dbg_f, "), returning copy\n");
fprintf(debug_file, "), returning copy\n");
return retval;
}
@ -161,29 +178,29 @@ dbg_objfmt_declare_data_copy(SymVisibility vis, /*@only@*/ void *data)
static void
dbg_objfmt_declare_data_delete(SymVisibility vis, /*@only@*/ void *data)
{
fprintf(dbg_f, "%*sdeclare_data_delete(", indent_level, "");
fprintf(debug_file, "%*sdeclare_data_delete(", indent_level, "");
switch (vis) {
case SYM_LOCAL:
fprintf(dbg_f, "Local, ");
fprintf(debug_file, "Local, ");
break;
case SYM_GLOBAL:
fprintf(dbg_f, "Global, ");
fprintf(debug_file, "Global, ");
break;
case SYM_COMMON:
fprintf(dbg_f, "Common, ");
fprintf(debug_file, "Common, ");
break;
case SYM_EXTERN:
fprintf(dbg_f, "Extern, ");
fprintf(debug_file, "Extern, ");
break;
}
if (vis == SYM_COMMON) {
expr_print(dbg_f, data);
expr_print(debug_file, data);
expr_delete(data);
} else {
fprintf(dbg_f, "%p", data);
fprintf(debug_file, "%p", data);
xfree(data);
}
fprintf(dbg_f, ")\n");
fprintf(debug_file, ")\n");
}
static void
@ -203,11 +220,11 @@ static int
dbg_objfmt_directive(const char *name, valparamhead *valparams,
/*@null@*/ valparamhead *objext_valparams)
{
fprintf(dbg_f, "%*sdirective(\"%s\", ", indent_level, "", name);
vps_print(dbg_f, valparams);
fprintf(dbg_f, ", ");
vps_print(dbg_f, objext_valparams);
fprintf(dbg_f, "), returning 0 (recognized)\n");
fprintf(debug_file, "%*sdirective(\"%s\", ", indent_level, "", name);
vps_print(debug_file, valparams);
fprintf(debug_file, ", ");
vps_print(debug_file, objext_valparams);
fprintf(debug_file, "), returning 0 (recognized)\n");
return 0; /* dbg format "recognizes" all directives */
}
@ -219,7 +236,8 @@ objfmt dbg_objfmt = {
".text",
32,
dbg_objfmt_initialize,
dbg_objfmt_finalize,
dbg_objfmt_output,
dbg_objfmt_cleanup,
dbg_objfmt_sections_switch,
dbg_objfmt_section_data_delete,
dbg_objfmt_section_data_print,

Loading…
Cancel
Save