<commit_before>/* outas86.c	output routines for the Netwide Assembler to produce
 *		Linux as86 (bin86-0.3) object files
 *
 * The Netwide Assembler is copyright (C) 1996 <NAME> and
 * <NAME>. All rights reserved. The software is
 * redistributable under the license given in the file "LICENSE"
 * distributed in the NASM archive.
 */

#include "compiler.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>

#include "nasm.h"
#include "nasmlib.h"
#include "saa.h"
#include "raa.h"
#include "outform.h"
#include "outlib.h"

#ifdef OF_AS86

struct Piece {
    struct Piece *next;
    int type;                   /* 0 = absolute, 1 = seg, 2 = sym */
    int32_t offset;		/* relative offset */
    int number;			/* symbol/segment number (4=bss) */
    int32_t bytes;	        /* size of reloc or of absolute data */
    bool relative;		/* relative address? */
};

struct Symbol {
    int32_t strpos;		/* string table position of name */
    int flags;                  /* symbol flags */
    int segment;                /* 4=bss at this point */
    int32_t value;		/* address, or COMMON variable size */
};

/*
 * Section IDs - used in Piece.number and Symbol.segment.
 */
#define SECT_TEXT 0             /* text section */
#define SECT_DATA 3             /* data section */
#define SECT_BSS 4              /* bss section */

/*
 * Flags used in Symbol.flags.
 */
#define SYM_ENTRY (1<<8)
#define SYM_EXPORT (1<<7)
#define SYM_IMPORT (1<<6)
#define SYM_ABSOLUTE (1<<4)

struct Section {
    struct SAA *data;
    uint32_t datalen, size, len;
    int32_t index;
    struct Piece *head, *last, **tail;
};

static char as86_module[FILENAME_MAX];

static struct Section stext, sdata;
static uint32_t bsslen;
static int32_t bssindex;

static struct SAA *syms;
static uint32_t nsyms;

static struct RAA *bsym;

static struct SAA *strs;
static uint32_t strslen;

static int as86_reloc_size;

static FILE *as86fp;
static efunc error;

static void as86_write(void);
static void as86_write_section(struct Section *, int);
static int as86_add_string(char *name);
static void as86_sect_write(struct Section *, const uint8_t *,
                            uint32_t);

static void as86_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
{
    as86fp = fp;
    error = errfunc;
    (void)ldef;                 /* placate optimisers */
    (void)eval;
    stext.data = saa_init(1L);
    stext.datalen = 0L;
    stext.head = stext.last = NULL;
    stext.tail = &stext.head;
    sdata.data = saa_init(1L);
    sdata.datalen = 0L;
    sdata.head = sdata.last = NULL;
    sdata.tail = &sdata.head;
    bsslen =
        stext.len = stext.datalen = stext.size =
        sdata.len = sdata.datalen = sdata.size = 0;
    stext.index = seg_alloc();
    sdata.index = seg_alloc();
    bssindex = seg_alloc();
    syms = saa_init((int32_t)sizeof(struct Symbol));
    nsyms = 0;
    bsym = raa_init();
    strs = saa_init(1L);
    strslen = 0;

    as86_add_string(as86_module);
}

static void as86_cleanup(int debuginfo)
{
    struct Piece *p;

    (void)debuginfo;

    as86_write();
    fclose(as86fp);
    saa_free(stext.data);
    while (stext.head) {
        p = stext.head;
        stext.head = stext.head->next;
        nasm_free(p);
    }
    saa_free(sdata.data);
    while (sdata.head) {
        p = sdata.head;
        sdata.head = sdata.head->next;
        nasm_free(p);
    }
    saa_free(syms);
    raa_free(bsym);
    saa_free(strs);
}

static int32_t as86_section_names(char *name, int pass, int *bits)
{

    (void)pass;

    /*
     * Default is 16 bits.
     */
    if (!name)
        *bits = 16;

    if (!name)
        return stext.index;

    if (!strcmp(name, ".text"))
        return stext.index;
    else if (!strcmp(name, ".data"))
        return sdata.index;
    else if (!strcmp(name, ".bss"))
        return bssindex;
    else
        return NO_SEG;
}

static int as86_add_string(char *name)
{
    int pos = strslen;
    int length = strlen(name);

    saa_wbytes(strs, name, (int32_t)(length + 1));
    strslen += 1 + length;

    return pos;
}

static void as86_deflabel(char *name, int32_t segment, int64_t offset,
                          int is_global, char *special)
{
    struct Symbol *sym;

    if (special)
        error(ERR_NONFATAL, "as86 format does not support any"
              " special symbol types");

    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
        error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
        return;
    }

    sym = saa_wstruct(syms);

    sym->strpos = as86_add_string(name);
    sym->flags = 0;
    if (segment == NO_SEG)
        sym->flags |= SYM_ABSOLUTE, sym->segment = 0;
    else if (segment == stext.index)
        sym->segment = SECT_TEXT;
    else if (segment == sdata.index)
        sym->segment = SECT_DATA;
    else if (segment == bssindex)
        sym->segment = SECT_BSS;
    else {
        sym->flags |= SYM_IMPORT;
        sym->segment = 15;
    }

    if (is_global == 2)
        sym->segment = 3;       /* already have IMPORT */

    if (is_global && !(sym->flags & SYM_IMPORT))
        sym->flags |= SYM_EXPORT;

    sym->value = offset;

    /*
     * define the references from external-symbol segment numbers
     * to these symbol records.
     */<commit_msg>Add entry point support to as86 backend<commit_after>/* outas86.c	output routines for the Netwide Assembler to produce
 *		Linux as86 (bin86-0.3) object files
 *
 * The Netwide Assembler is copyright (C) 1996 <NAME> and
 * <NAME>. All rights reserved. The software is
 * redistributable under the license given in the file "LICENSE"
 * distributed in the NASM archive.
 */

#include "compiler.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <inttypes.h>

#include "nasm.h"
#include "nasmlib.h"
#include "saa.h"
#include "raa.h"
#include "outform.h"
#include "outlib.h"

#ifdef OF_AS86

struct Piece {
    struct Piece *next;
    int type;                   /* 0 = absolute, 1 = seg, 2 = sym */
    int32_t offset;		/* relative offset */
    int number;			/* symbol/segment number (4=bss) */
    int32_t bytes;	        /* size of reloc or of absolute data */
    bool relative;		/* relative address? */
};

struct Symbol {
    int32_t strpos;		/* string table position of name */
    int flags;                  /* symbol flags */
    int segment;                /* 4=bss at this point */
    int32_t value;		/* address, or COMMON variable size */
};

/*
 * Section IDs - used in Piece.number and Symbol.segment.
 */
#define SECT_TEXT 0             /* text section */
#define SECT_DATA 3             /* data section */
#define SECT_BSS 4              /* bss section */

/*
 * Flags used in Symbol.flags.
 */
#define SYM_ENTRY (1<<8)
#define SYM_EXPORT (1<<7)
#define SYM_IMPORT (1<<6)
#define SYM_ABSOLUTE (1<<4)

struct Section {
    struct SAA *data;
    uint32_t datalen, size, len;
    int32_t index;
    struct Piece *head, *last, **tail;
};

static char as86_module[FILENAME_MAX];

static struct Section stext, sdata;
static uint32_t bsslen;
static int32_t bssindex;

static struct SAA *syms;
static uint32_t nsyms;

static struct RAA *bsym;

static struct SAA *strs;
static uint32_t strslen;

static int as86_reloc_size;

static FILE *as86fp;
static efunc error;

static void as86_write(void);
static void as86_write_section(struct Section *, int);
static int as86_add_string(char *name);
static void as86_sect_write(struct Section *, const uint8_t *,
                            uint32_t);

static void as86_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
{
    as86fp = fp;
    error = errfunc;
    (void)ldef;                 /* placate optimisers */
    (void)eval;
    stext.data = saa_init(1L);
    stext.datalen = 0L;
    stext.head = stext.last = NULL;
    stext.tail = &stext.head;
    sdata.data = saa_init(1L);
    sdata.datalen = 0L;
    sdata.head = sdata.last = NULL;
    sdata.tail = &sdata.head;
    bsslen =
        stext.len = stext.datalen = stext.size =
        sdata.len = sdata.datalen = sdata.size = 0;
    stext.index = seg_alloc();
    sdata.index = seg_alloc();
    bssindex = seg_alloc();
    syms = saa_init((int32_t)sizeof(struct Symbol));
    nsyms = 0;
    bsym = raa_init();
    strs = saa_init(1L);
    strslen = 0;

    as86_add_string(as86_module);
}

static void as86_cleanup(int debuginfo)
{
    struct Piece *p;

    (void)debuginfo;

    as86_write();
    fclose(as86fp);
    saa_free(stext.data);
    while (stext.head) {
        p = stext.head;
        stext.head = stext.head->next;
        nasm_free(p);
    }
    saa_free(sdata.data);
    while (sdata.head) {
        p = sdata.head;
        sdata.head = sdata.head->next;
        nasm_free(p);
    }
    saa_free(syms);
    raa_free(bsym);
    saa_free(strs);
}

static int32_t as86_section_names(char *name, int pass, int *bits)
{

    (void)pass;

    /*
     * Default is 16 bits.
     */
    if (!name)
        *bits = 16;

    if (!name)
        return stext.index;

    if (!strcmp(name, ".text"))
        return stext.index;
    else if (!strcmp(name, ".data"))
        return sdata.index;
    else if (!strcmp(name, ".bss"))
        return bssindex;
    else
        return NO_SEG;
}

static int as86_add_string(char *name)
{
    int pos = strslen;
    int length = strlen(name);

    saa_wbytes(strs, name, (int32_t)(length + 1));
    strslen += 1 + length;

    return pos;
}

static void as86_deflabel(char *name, int32_t segment, int64_t offset,
                          int is_global, char *special)
{
    int is_start = 0;
    struct Symbol *sym;

    if (special)
        error(ERR_NONFATAL, "as86 format does not support any"
              " special symbol types");


    if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
      if(strcmp(name, "..start")) {
        error(ERR_NONFATAL, "custom unrecognised special symbol `%s'", name);
        return;
      } else {
  is_start = 1;
      }
    }

    sym = saa_wstruct(syms);

    sym->strpos = as86_add_string(name);
    sym->flags = 0;

    if(is_start)
      sym->flags = SYM_ENTRY;

    if (segment == NO_SEG)
        sym->flags |= SYM_ABSOLUTE, sym->segment = 0;
    else if (segment == stext.index)
        sym->segment = SECT_TEXT;
    else if (segment == sdata.index)
        sym->segment = SECT_DATA;
    else if (segment == bssindex)
        sym->segment = SECT_BSS;
    else {
        sym->flags |= SYM_IMPORT;
        sym->segment = 15;
    }

    if (is_global == 2)
        sym->segment = 3;       /* already have IMPORT */

    if (is_global && !(sym->flags & SYM_IMPORT))
        sym->flags |= SYM_EXPORT;

    sym->value = offset;

    /*
     * define the references from external-symbol segment numbers
     * to these symbol records.
     */
{'fraction_non_alphanumeric': 0.12689744539059608, 'fraction_numerical': 0.02332469455757127, 'mean_word_length': 2.421469284357188, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4691900', 'n_tokens_mistral': 4032, 'n_tokens_neox': 3848, 'n_words': 1014}