Example #1
0
void dumplits(
    int size, int pr_label ,
    int queueptr,int queuelab,
    unsigned char *queue)
{
    int j, k,lit ;

    if ( queueptr ) {
        if ( pr_label ) {
            output_section("rodata_compiler"); // output_section("text");
            prefix(); queuelabel(queuelab) ;
            col() ; nl();
        }
        k = 0 ;
        while ( k < queueptr ) {
            /* pseudo-op to define byte */
            if (infunc) j=1;
            else j=10;
            if (size == 1) defbyte();
            else if (size == 4) deflong();
            else if (size == 0 ) { defmesg(); j=30; }
            else defword();
            while ( j-- ) {
                if (size==0) {
                    lit=getint(queue+k,1);
                    if (lit >= 32 && lit <= 126  && lit != '"' && lit != '\\' ) outbyte(lit);
                    else {
                        outstr("\"\n");
                        defbyte();
                        outdec(lit);
                        nl();
                        lit=0;
                    }
                    k++;
                    if ( j == 0 || k >=queueptr || lit == 0 ) {
                        if (lit) outbyte('"');
                        nl();
                        break;
                    }
                } else {
                    outdec(getint(queue+k, size));
                    k += size ;
                    if ( j == 0 || k >= queueptr ) {
                        nl();           /* need <cr> */
                        break;
                    }
                    outbyte(',');   /* separate bytes */
                }
            }
        }
        output_section("code_compiler"); // output_section("code");
    }
    nl();
}
Example #2
0
void
#endif

dumpvars()
{
    int ident,type,storage;
    SYMBOL *ptr;

    if (!glbcnt)
        return;

/* Start at the start! */
    glbptr=STARTGLB;
    outstr("; --- Start of Static Variables ---\n\n");
/* Two different handlings, if an application then use defvars construct
 * if not, then just drop em using defs!
 *
 * Even more handlings...if asz80 used we dump into data sectio
 */

    output_section("bss_compiler");  // output_section("bss");


    ptr=STARTGLB;
    while (ptr < ENDGLB)
    {
        if (ptr->name[0] != 0 && ptr->name[0] != '0' )
        {
            ident=ptr->ident;
            type =ptr->type;
            storage=ptr->storage;
            if (ident !=ENUM && type !=ENUM && ident != MACRO && ident != FUNCTION && storage != EXTERNAL && storage != DECLEXTN && storage != EXTERNP && storage != LSTKEXT && storage!=TYPDEF )
            {
                prefix();
                outname(ptr->name,1);
                col();
                defstorage();
                outdec(ptr->size);
                nl();
            }
        }
        ++ptr;
    }

    /* Switch back to standard section */
    output_section("code_compiler");  // output_section("code");
}
Example #3
0
File: pass2.c Project: bihai/xchain
/*
 * pass2() creates the output file and the memory buffer to create the file
 * into.  It drives the process to get everything copied into the buffer for
 * the output file.  It then writes the output file and deallocates the buffer.
 */ 
extern
void
pass2(void)
{
    unsigned long i, j, section_type;
    struct object_list *object_list, **p;
#ifndef RLD
    int mode;
    struct stat stat_buf;
    kern_return_t r;

	/*
	 * In UNIX standard conformance mode we are not allowed to replace
	 * a file that is not writeable.
	 */
	if(get_unix_standard_mode() == TRUE && 
	   access(outputfile, F_OK) == 0 &&
	   access(outputfile, W_OK) == -1)
	    system_fatal("can't write output file: %s", outputfile);

	/*
	 * Create the output file.  The unlink() is done to handle the problem
	 * when the outputfile is not writable but the directory allows the
	 * file to be removed (since the file may not be there the return code
	 * of the unlink() is ignored).
	 */
	(void)unlink(outputfile);
	if((fd = open(outputfile, O_WRONLY | O_CREAT | O_TRUNC, 0777)) == -1)
	    system_fatal("can't create output file: %s", outputfile);
#ifdef F_NOCACHE
        /* tell filesystem to NOT cache the file when reading or writing */
	(void)fcntl(fd, F_NOCACHE, 1);
#endif
	if(fstat(fd, &stat_buf) == -1)
	    system_fatal("can't stat file: %s", outputfile);
	/*
	 * Turn the execute bits on or off depending if there are any undefined
	 * symbols in the output file.  If the file existed before the above
	 * open() call the creation mode in that call would have been ignored
	 * so it has to be set explicitly in any case.
	 */
	if(output_mach_header.flags & MH_NOUNDEFS ||
	   (has_dynamic_linker_command && output_for_dyld))
	    mode = (stat_buf.st_mode & 0777) | (0111 & ~umask(0));
	else
	    mode = (stat_buf.st_mode & 0777) & ~0111;
	if(fchmod(fd, mode) == -1)
	    system_fatal("can't set execution permissions output file: %s",
			 outputfile);

	/*
	 * Create the buffer to copy the parts of the output file into.
	 */
	if((r = vm_allocate(mach_task_self(), (vm_address_t *)&output_addr,
			    output_size, TRUE)) != KERN_SUCCESS)
	    mach_fatal(r, "can't vm_allocate() buffer for output file of size "
		       "%lu", output_size);

	/*
	 * Set up for flushing pages to the output file as they fill up.
	 */
	if(flush)
	    setup_output_flush();

	/*
	 * Make sure pure_instruction sections are padded with nop's.
	 */
	nop_pure_instruction_scattered_sections();

#endif /* !defined(RLD) */

	/*
	 * The strings indexes for the merged string blocks need to be set
	 * before the dylib tables are output because the module names are in
	 * them as well as the merged symbol names.
	 */
	set_merged_string_block_indexes();

#ifndef RLD
	/*
	 * Copy the dylib tables into the output file.  This is done before the
	 * sections are outputted so that the indexes to the local and external
	 * relocation entries for each object can be used as running indexes as
	 * each section in the object is outputted.
	 */
	if(filetype == MH_DYLIB)
	    output_dylib_tables();
#endif /* !defined(RLD) */

	/*
	 * Create the array of pointers to merged sections in the output file
	 * so the relocation routines can use it to set the 'referenced' fields
	 * in the merged section structures.
	 */
	create_output_sections_array();

	/*
	 * Copy the merged literal sections and the sections created from files
	 * into the output object file.
	 */
	output_literal_sections();
#ifndef RLD
	output_sections_from_files();
#endif /* !defined(RLD) */

	/*
	 * For each non-literal content section in each object file loaded 
	 * relocate it into the output file (along with the relocation entries).
	 * Then relocate local symbols into the output file for the loaded
	 * objects.
	 */
	for(p = &objects; *p; p = &(object_list->next)){
	    object_list = *p;
	    for(i = 0; i < object_list->used; i++){
		cur_obj = &(object_list->object_files[i]);
		/* print the object file name if tracing */
		if(trace){
		    print_obj_name(cur_obj);
		    print("\n");
		}
		if(cur_obj->dylib)
		    continue;
		if(cur_obj->bundle_loader)
		    continue;
		if(cur_obj->dylinker)
		    continue;
		if(cur_obj != base_obj){
		    for(j = 0; j < cur_obj->nsection_maps; j++){
			if(cur_obj->section_maps[j].s->flags & S_ATTR_DEBUG)
			    continue;
#ifdef RLD
			if(cur_obj->set_num == cur_set)
#endif /* RLD */
			{
			    section_type = (cur_obj->section_maps[j].s->flags &
                                                   SECTION_TYPE);
			    if(section_type == S_REGULAR ||
			       section_type == S_SYMBOL_STUBS ||
			       section_type == S_NON_LAZY_SYMBOL_POINTERS ||
			       section_type == S_LAZY_SYMBOL_POINTERS ||
			       section_type == S_COALESCED ||
			       section_type == S_MOD_INIT_FUNC_POINTERS ||
			       section_type == S_MOD_TERM_FUNC_POINTERS){
				output_section(&(cur_obj->section_maps[j]));
			    }
			}
		    }
		}
		output_local_symbols();
#if defined(VM_SYNC_DEACTIVATE) && !defined(_POSIX_C_SOURCE) && !defined(__CYGWIN__)
		vm_msync(mach_task_self(), (vm_address_t)cur_obj->obj_addr,
			 (vm_size_t)cur_obj->obj_size, VM_SYNC_DEACTIVATE);
#endif /* VM_SYNC_DEACTIVATE */
	    }
	}
	/*
	 * If there were errors in output_section() then return as so not
	 * to cause later internal errors.
	 */
	if(errors != 0)
	    return;

#ifdef RLD
	/*
	 * For each content section clean up the data structures not needed
	 * after rld is run.  This must be done after ALL the sections are
	 * output'ed because the fine relocation entries could be used by any
	 * of the sections.
	 */
	for(p = &objects; *p; p = &(object_list->next)){
	    object_list = *p;
	    for(i = 0; i < object_list->used; i++){
		cur_obj = &(object_list->object_files[i]);
		for(j = 0; j < cur_obj->nsection_maps; j++){
		    if(cur_obj->section_maps[j].nfine_relocs != 0){
			free(cur_obj->section_maps[j].fine_relocs);
			cur_obj->section_maps[j].fine_relocs = NULL;
			cur_obj->section_maps[j].nfine_relocs = 0;
		    }
		}
		if(cur_obj->nundefineds != 0){
		    free(cur_obj->undefined_maps);
		    cur_obj->undefined_maps = NULL;
		    cur_obj->nundefineds = 0;
		}
	    }
	}
#endif /* RLD */

	/*
	 * Set the SG_NORELOC flag in the segments that had no relocation to
	 * or for them.
	 */
	set_SG_NORELOC_flags();

#ifndef SA_RLD
	/*
	 * Copy the indirect symbol table into the output file.
	 */
	output_indirect_symbols();
#endif /* SA_RLD */

	/*
	 * Copy the merged symbol table into the output file.
	 */
	output_merged_symbols();

	/*
	 * Copy the headers into the output file.
	 */
	output_headers();

#ifndef RLD
	if(flush){
	    /*
	     * Flush the sections that have been scatter loaded.
	     */
	    flush_scatter_copied_sections();
	    /*
	     * flush the remaining part of the object file that is not a full
	     * page.
	     */
	    final_output_flush();
	}
	else{
	    /*
	     * Write the entire object file.
	     */
	    if(write(fd, output_addr, output_size) != (int)output_size)
		system_fatal("can't write output file");

	    if((r = vm_deallocate(mach_task_self(), (vm_address_t)output_addr,
				  output_size)) != KERN_SUCCESS)
		mach_fatal(r, "can't vm_deallocate() buffer for output file");
	}
#ifdef F_NOCACHE
	/* re-enable caching of file reads/writes */
	(void)fcntl(fd, F_NOCACHE, 0);
#endif
	if(close(fd) == -1)
	    system_fatal("can't close output file");
#endif /* RLD */
}
Example #4
0
/*
 * initialise global object
 */
int initials(char *sname,
             int type, int ident, int dim, int more,
             TAG_SYMBOL * tag, char zfar)
{
    int size, desize = 0;
    int olddim = dim;


    if (cmatch('=')) {
        /* initialiser present */
        defstatic = 1;		/* So no 2nd redefine djm */
        gltptr = 0;
        glblab = getlabel();
        if (dim == 0)
            dim = -1;
        switch (type) {
        case CCHAR:
            size = 1;
            break;
        case LONG:
            size = 4;
            break;
        case CINT:
        default:
            size = 2;
        }
	    
        output_section("data_compiler");  // output_section("text");
        prefix();
        outname(sname, YES);
        col();
        nl();

        if (cmatch('{')) {
            /* aggregate initialiser */
            if ((ident == POINTER || ident == VARIABLE) && type == STRUCT) {
                /* aggregate is structure or pointer to structure */
                dim = 0; olddim = 1;
                if (ident == POINTER)
                    point();
                str_init(tag);
            } else {
                /* aggregate is not struct or struct pointer */
                agg_init(size, type, ident, &dim, more, tag);
            }
            needchar('}');
        } else {
            /* single initialiser */
            init(size, ident, &dim, more, 0, 0);
        }


        /* dump literal queue and fill tail of array with zeros */
        if ((ident == ARRAY && more == CCHAR) || type == STRUCT) {
            if (type == STRUCT) {
                dumpzero(tag->size, dim);
                desize = dim < 0 ? abs(dim+1)*tag->size : olddim * tag->size;
            } else { /* Handles unsized arrays of chars */
                dumpzero(size, dim);
                dim = dim < 0 ? abs(dim+1) : olddim;
                cscale(type,tag,&dim);
                desize = dim;
            }
            dumplits(0, YES, gltptr, glblab, glbq);
        } else {
            if (!(ident == POINTER && type == CCHAR)) {
                dumplits(((size == 1) ? 0 : size), NO, gltptr, glblab,glbq);
                if ( type != CCHAR )  /* Already dumped by init? */
                    desize = dumpzero(size, dim);
                dim = dim < 0 ? abs(dim+1) : olddim;
                cscale(type,tag,&dim);
                desize = dim;
            }             
        }
        output_section("code_compiler");  // output_section("code");
    } else {
        char *dosign, *typ;
        dosign = "";
        if (ident == ARRAY && (dim == 0)) {
            typ = ExpandType(more, &dosign, (tag - tagtab));
            warning(W_NULLARRAY, dosign, typ);
        }
        /* no initialiser present, let loader insert zero */
        if (ident == POINTER)
            type = (zfar ? CPTR : CINT);
        cscale(type, tag, &dim);
        desize = dim;
    }
    return (desize);
}