minix/commands/i386/gas2ack/globals.c
Tomas Hruby 41d481b065 gas2ack
- an asmconv based tool for conversion from GNU ia32 assembly to ACK assembly
    
    - in contrast to asmconv it is a one way tool only
    
    - as the GNU assembly in Minix does not prefix global C symbols with _ gas2ack
      detects such symbols and prefixes them to be compliant with the ACK convention
    
    - gas2ack preserves comments and unexpanded macros
    
    - bunch of fixes to the asmconv GNU->ACK direction
    
    - support of more instructions that ACK does not know but are in use in Minix
    
    - it is meant as a temporary solution as long as ACK will be a supported
      compiler for the core system
2009-10-30 15:57:35 +00:00

134 lines
2 KiB
C

/*
* Table of all global definitions. Since the ack convention is to prepend
* syms with '_' for C interfacing, we need to know about them and add/remove
* teh '_' as neccessary
*/
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "asm86.h"
/* this should be fine for common minix assembly files */
#define SYM_MAX 1024
#define SYM_MAX_LEN 64
struct sym {
char name[SYM_MAX_LEN];
int gl;
};
static struct sym syms[SYM_MAX];
static int syms_num = 0;
static struct sym * sym_exists(const char * n)
{
int i;
for (i = 0; i < syms_num; i++) {
if (strcmp(syms[i].name, n) == 0)
return &syms[i];
}
return NULL;
}
static int is_local_label_ref(const char *n)
{
int i;
int l = strlen(n);
for(i = 0; i < l - 1; i++)
if (!isdigit(n[i]))
return 0;
if (n[l-1] != 'b' && n[l-1] != 'f')
return 0;
return 1;
}
static int is_hex(const char *n)
{
int i;
for(i = 0; n[i]; i++)
if (!isxdigit(n[i]))
return 0;
return 1;
}
static int is_dec(const char *n)
{
int i;
for(i = 0; n[i]; i++)
if (!isdigit(n[i]))
return 0;
return 1;
}
static int is_number(const char * n)
{
if (n[0] == '0' && n[1] == 'x')
return is_hex(n + 2);
else
return is_dec(n);
}
int syms_is_global(const char * n)
{
struct sym *s;
if (!n || is_number(n) || is_local_label_ref(n) || isregister(n))
return 0;
/* if not found, it must be extern -> global */
if (!(s = sym_exists(n)))
return 1;
return s->gl;
}
static int add(const char * n, int isgl)
{
if (syms_num >= SYM_MAX)
return -ENOMEM;
if (!n || strlen(n) >= SYM_MAX_LEN)
return -EINVAL;
/* ignore numbers */
if (is_number(n))
return 0;
strcpy(syms[syms_num].name, n);
syms[syms_num].gl = isgl;
syms_num++;
return 0;
}
int syms_add(const char *n)
{
return add(n, 0);
}
int syms_add_global(const char *n)
{
return add(n, 1);
}
void syms_add_global_csl(expression_t * exp)
{
if (!exp)
return;
if (exp->operator == ',') {
syms_add_global_csl(exp->left);
syms_add_global_csl(exp->right);
}
else {
syms_add_global(exp->name);
}
}