From 42017a611590d0ca764ab017aad0abdf0e6cf633 Mon Sep 17 00:00:00 2001 From: Cyrill Gorcunov Date: Thu, 22 Apr 2010 14:25:21 +0400 Subject: coff: Use predefined macros instead of numbers and style fix Signed-off-by: Cyrill Gorcunov --- output/outcoff.c | 305 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 160 insertions(+), 145 deletions(-) (limited to 'output') diff --git a/output/outcoff.c b/output/outcoff.c index 841e5fe7..7123db3a 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * - * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * + * Copyright 1996-2010 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -14,7 +14,7 @@ * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF @@ -31,9 +31,9 @@ * * ----------------------------------------------------------------------- */ -/* - * outcoff.c output routines for the Netwide Assembler to produce - * COFF object files (for DJGPP and Win32) +/* + * outcoff.c output routines for the Netwide Assembler to produce + * COFF object files (for DJGPP and Win32) */ #include "compiler.h" @@ -107,8 +107,8 @@ static int32_t imagebase_sect; struct Reloc { struct Reloc *next; - int32_t address; /* relative to _start_ of section */ - int32_t symbol; /* symbol number */ + int32_t address; /* relative to _start_ of section */ + int32_t symbol; /* symbol number */ enum { SECT_SYMBOLS, ABS_SYMBOL, @@ -119,13 +119,13 @@ struct Reloc { struct Symbol { char name[9]; - int32_t strpos; /* string table position of name */ - int32_t value; /* address, or COMMON variable size */ + int32_t strpos; /* string table position of name */ + int32_t value; /* address, or COMMON variable size */ int section; /* section number where it's defined * - in COFF codes, not NASM codes */ - bool is_global; /* is it a global symbol or not? */ - int16_t type; /* 0 - notype, 0x20 - function */ - int32_t namlen; /* full name length */ + bool is_global; /* is it a global symbol or not? */ + int16_t type; /* 0 - notype, 0x20 - function */ + int32_t namlen; /* full name length */ }; static char coff_infile[FILENAME_MAX]; @@ -136,7 +136,7 @@ struct Section { int nrelocs; int32_t index; struct Reloc *head, **tail; - uint32_t flags; /* section flags */ + uint32_t flags; /* section flags */ char name[9]; int32_t pos, relpos; }; @@ -184,13 +184,17 @@ struct Section { #define XDATA_FLAGS \ (IMAGE_SCN_CNT_INITIALIZED_DATA | \ IMAGE_SCN_ALIGN_8BYTES | \ - IMAGE_SCN_MEM_READ) + IMAGE_SCN_MEM_READ) + +#define INFO_FLAGS \ + (IMAGE_SCN_ALIGN_1BYTES | \ + IMAGE_SCN_LNK_INFO | \ + IMAGE_SCN_LNK_REMOVE) #define TEXT_FLAGS ((win32 | win64) ? TEXT_FLAGS_WIN : TEXT_FLAGS_DOS) #define DATA_FLAGS ((win32 | win64) ? DATA_FLAGS_WIN : DATA_FLAGS_DOS) #define BSS_FLAGS ((win32 | win64) ? BSS_FLAGS_WIN : BSS_FLAGS_DOS) #define RDATA_FLAGS ((win32 | win64) ? RDATA_FLAGS_WIN : RDATA_FLAGS_DOS) -#define INFO_FLAGS 0x00100A00L #define SECT_DELTA 32 static struct Section **sects; @@ -209,8 +213,7 @@ static struct SAA *strs; static uint32_t strslen; static void coff_gen_init(void); -static void coff_sect_write(struct Section *, const uint8_t *, - uint32_t); +static void coff_sect_write(struct Section *, const uint8_t *, uint32_t); static void coff_write(void); static void coff_section_header(char *, int32_t, int32_t, int32_t, int32_t, int, int32_t); static void coff_write_relocs(struct Section *); @@ -301,7 +304,7 @@ static int coff_make_section(char *name, uint32_t flags) s->flags = flags; if (nsects >= sectlen) { - sectlen += SECT_DELTA; + sectlen += SECT_DELTA; sects = nasm_realloc(sects, sectlen * sizeof(*sects)); } sects[nsects++] = s; @@ -391,7 +394,7 @@ static int32_t coff_section_names(char *name, int pass, int *bits) " to better than 64-byte boundaries"); else { align_and = ~0x00F00000L; - align_or = ilog2_32(align) << 20; + align_or = ilog2_32(align) << 20; } } } @@ -409,10 +412,10 @@ static int32_t coff_section_names(char *name, int pass, int *bits) flags = RDATA_FLAGS; else if (!strcmp(name, ".bss")) flags = BSS_FLAGS; - else if (win64 && !strcmp(name, ".pdata")) - flags = PDATA_FLAGS; - else if (win64 && !strcmp(name, ".xdata")) - flags = XDATA_FLAGS; + else if (win64 && !strcmp(name, ".pdata")) + flags = PDATA_FLAGS; + else if (win64 && !strcmp(name, ".xdata")) + flags = XDATA_FLAGS; else flags = TEXT_FLAGS; } @@ -441,15 +444,15 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, " special symbol types"); if (name[0] == '.' && name[1] == '.' && name[2] != '@') { - if (strcmp(name,WRT_IMAGEBASE)) + if (strcmp(name,WRT_IMAGEBASE)) nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name); return; } if (strlen(name) > 8) { - size_t nlen = strlen(name)+1; + size_t nlen = strlen(name)+1; saa_wbytes(strs, name, nlen); - strslen += nlen; + strslen += nlen; } else pos = -1; @@ -460,7 +463,7 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, if (pos == -1) strcpy(sym->name, name); sym->is_global = !!is_global; - sym->type = 0; /* Default to T_NULL (no type) */ + sym->type = 0; /* Default to T_NULL (no type) */ if (segment == NO_SEG) sym->section = -1; /* absolute symbol */ else { @@ -483,9 +486,8 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, * define the references from external-symbol segment numbers * to these symbol records. */ - if (sym->section == 0) { + if (sym->section == 0) bsym = raa_write(bsym, segment, nsyms); - } if (segment != NO_SEG) symval = raa_write(symval, segment, sym->section ? 0 : sym->value); @@ -494,7 +496,7 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, } static int32_t coff_add_reloc(struct Section *sect, int32_t segment, - int16_t type) + int16_t type) { struct Reloc *r; @@ -503,17 +505,18 @@ static int32_t coff_add_reloc(struct Section *sect, int32_t segment, r->next = NULL; r->address = sect->len; - if (segment == NO_SEG) + if (segment == NO_SEG) { r->symbol = 0, r->symbase = ABS_SYMBOL; - else { + } else { int i; r->symbase = REAL_SYMBOLS; - for (i = 0; i < nsects; i++) + for (i = 0; i < nsects; i++) { if (segment == sects[i]->index) { r->symbol = i * 2; r->symbase = SECT_SYMBOLS; break; } + } if (r->symbase == REAL_SYMBOLS) r->symbol = raa_read(bsym, segment); } @@ -526,12 +529,12 @@ static int32_t coff_add_reloc(struct Section *sect, int32_t segment, */ if (r->symbase == REAL_SYMBOLS && !(win32 | win64)) return raa_read(symval, segment); - else - return 0; + + return 0; } static void coff_out(int32_t segto, const void *data, - enum out_type type, uint64_t size, + enum out_type type, uint64_t size, int32_t segment, int32_t wrt) { struct Section *s; @@ -554,11 +557,12 @@ static void coff_out(int32_t segto, const void *data, } s = NULL; - for (i = 0; i < nsects; i++) + for (i = 0; i < nsects; i++) { if (segto == sects[i]->index) { s = sects[i]; break; } + } if (!s) { int tempint; /* ignored */ if (segto != coff_section_names(".text", 2, &tempint)) @@ -568,9 +572,10 @@ static void coff_out(int32_t segto, const void *data, } /* magically default to 'wrt ..imagebase' in .pdata and .xdata */ - if (win64 && wrt == NO_SEG && - (!strcmp(s->name,".pdata") || !strcmp(s->name,".xdata"))) - wrt = imagebase_sect; + if (win64 && wrt == NO_SEG) { + if (!strcmp(s->name,".pdata") || !strcmp(s->name,".xdata")) + wrt = imagebase_sect; + } if (!s->data && type != OUT_RESERVE) { nasm_error(ERR_WARNING, "attempt to initialize memory in" @@ -592,10 +597,10 @@ static void coff_out(int32_t segto, const void *data, coff_sect_write(s, data, size); } else if (type == OUT_ADDRESS) { if (!(win64)) { - if (size != 4 && (segment != NO_SEG || wrt != NO_SEG)) + if (size != 4 && (segment != NO_SEG || wrt != NO_SEG)) { nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit" " relocations"); - else { + } else { int32_t fix = 0; if (segment != NO_SEG || wrt != NO_SEG) { if (wrt != NO_SEG) { @@ -615,17 +620,17 @@ static void coff_out(int32_t segto, const void *data, int32_t fix = 0; p = mydata; if (size == 8) { - if (wrt == imagebase_sect) { - nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt " - WRT_IMAGEBASE "' is a 32-bit operand"); - } + if (wrt == imagebase_sect) { + nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt " + WRT_IMAGEBASE "' is a 32-bit operand"); + } fix = coff_add_reloc(s, segment, IMAGE_REL_AMD64_ADDR64); WRITEDLONG(p, *(int64_t *)data + fix); coff_sect_write(s, mydata, size); } else { fix = coff_add_reloc(s, segment, - wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB: - IMAGE_REL_AMD64_ADDR32); + wrt == imagebase_sect ? IMAGE_REL_AMD64_ADDR32NB: + IMAGE_REL_AMD64_ADDR32); WRITELONG(p, *(int64_t *)data + fix); coff_sect_write(s, mydata, size); } @@ -646,7 +651,7 @@ static void coff_out(int32_t segto, const void *data, " segment base references"); } else fix = coff_add_reloc(s, segment, - win64 ? IMAGE_REL_AMD64_REL32 : IMAGE_REL_I386_REL32); + win64 ? IMAGE_REL_AMD64_REL32 : IMAGE_REL_I386_REL32); p = mydata; if (win32 | win64) { WRITELONG(p, *(int64_t *)data + 4 - size + fix); @@ -675,9 +680,9 @@ typedef struct tagString { #define EXPORT_SECTION_NAME ".drectve" #define EXPORT_SECTION_FLAGS INFO_FLAGS /* -#define EXPORT_SECTION_NAME ".text" -#define EXPORT_SECTION_FLAGS TEXT_FLAGS -*/ + * #define EXPORT_SECTION_NAME ".text" + * #define EXPORT_SECTION_FLAGS TEXT_FLAGS + */ static STRING *Exports = NULL; static struct Section *directive_sec; @@ -696,12 +701,12 @@ void AddExport(char *name) for (i = 0; i < nsects; i++) { if (!strcmp(EXPORT_SECTION_NAME, sects[i]->name)) break; - } + } if (i == nsects) - i = coff_make_section(EXPORT_SECTION_NAME, EXPORT_SECTION_FLAGS); + i = coff_make_section(EXPORT_SECTION_NAME, EXPORT_SECTION_FLAGS); - directive_sec = sects[i]; + directive_sec = sects[i]; Exports = newS; } else { while (rvp->next) { @@ -762,62 +767,68 @@ static int coff_directives(enum directives directive, char *value, int pass) } case D_SAFESEH: { - static int sxseg=-1; - int i; - - if (!win32) /* Only applicable for -f win32 */ - return 0; - - if (sxseg==-1) - { for (i = 0; i < nsects; i++) - if (!strcmp(".sxdata",sects[i]->name)) - break; - if (i == nsects) - sxseg = coff_make_section(".sxdata",0x200); - else - sxseg = i; - } - /* pass0 == 2 is the only time when the full set of symbols are - guaranteed to be present; it is the final output pass. */ - if (pass0 == 2) { - uint32_t n; - saa_rewind(syms); - for (n = 0; n < nsyms; n++) { - struct Symbol *sym = saa_rstruct(syms); - bool equals; - - /* sym->strpos is biased by 4, because symbol - * table is prefixed with table length */ - if (sym->strpos >=4) { - char *name = nasm_malloc(sym->namlen+1); - saa_fread(strs, sym->strpos-4, name, sym->namlen); - name[sym->namlen] = '\0'; - equals = !strcmp(value,name); - nasm_free(name); - } - else - equals = !strcmp(value,sym->name); - - if (equals) { - /* this value arithmetics effectively reflects - * initsym in coff_write(): 2 for file, 1 for - * .absolute and two per each section */ - unsigned char value[4],*p=value; - WRITELONG(p,n + 2 + 1 + nsects*2); - coff_sect_write(sects[sxseg],value,4); - sym->type = 0x20; - break; - } - } - if (n == nsyms) { - nasm_error(ERR_NONFATAL, - "`safeseh' directive requires valid symbol"); - } - } - return 1; + static int sxseg=-1; + int i; + + if (!win32) /* Only applicable for -f win32 */ + return 0; + + if (sxseg == -1) { + for (i = 0; i < nsects; i++) + if (!strcmp(".sxdata",sects[i]->name)) + break; + if (i == nsects) + sxseg = coff_make_section(".sxdata", IMAGE_SCN_LNK_INFO); + else + sxseg = i; + } + /* + * pass0 == 2 is the only time when the full set of symbols are + * guaranteed to be present; it is the final output pass. + */ + if (pass0 == 2) { + uint32_t n; + saa_rewind(syms); + for (n = 0; n < nsyms; n++) { + struct Symbol *sym = saa_rstruct(syms); + bool equals; + + /* + * sym->strpos is biased by 4, because symbol + * table is prefixed with table length + */ + if (sym->strpos >=4) { + char *name = nasm_malloc(sym->namlen+1); + saa_fread(strs, sym->strpos-4, name, sym->namlen); + name[sym->namlen] = '\0'; + equals = !strcmp(value,name); + nasm_free(name); + } else { + equals = !strcmp(value,sym->name); + } + + if (equals) { + /* + * this value arithmetics effectively reflects + * initsym in coff_write(): 2 for file, 1 for + * .absolute and two per each section + */ + unsigned char value[4],*p=value; + WRITELONG(p,n + 2 + 1 + nsects*2); + coff_sect_write(sects[sxseg],value,4); + sym->type = 0x20; + break; + } + } + if (n == nsyms) { + nasm_error(ERR_NONFATAL, + "`safeseh' directive requires valid symbol"); + } + } + return 1; } default: - return 0; + return 0; } } @@ -830,17 +841,17 @@ static void coff_write(void) BuildExportTable(&Exports); if (win32) { - /* add default value for @feat.00, this allows to 'link /safeseh' */ - uint32_t n; + /* add default value for @feat.00, this allows to 'link /safeseh' */ + uint32_t n; - saa_rewind(syms); - for (n = 0; n < nsyms; n++) { + saa_rewind(syms); + for (n = 0; n < nsyms; n++) { struct Symbol *sym = saa_rstruct(syms); - if (sym->strpos == -1 && !strcmp("@feat.00",sym->name)) - break; - } - if (n == nsyms) - coff_deflabel("@feat.00",NO_SEG,1,0,NULL); + if (sym->strpos == -1 && !strcmp("@feat.00",sym->name)) + break; + } + if (n == nsyms) + coff_deflabel("@feat.00", NO_SEG, 1, 0, NULL); } /* @@ -865,14 +876,15 @@ static void coff_write(void) * Output the COFF header. */ if (win64) - fwriteint16_t(0x8664, ofile); /* MACHINE_x86-64 */ + i = IMAGE_FILE_MACHINE_AMD64; else - fwriteint16_t(0x014C, ofile); /* MACHINE_i386 */ - fwriteint16_t(nsects, ofile); /* number of sections */ - fwriteint32_t(time(NULL), ofile); /* time stamp */ - fwriteint32_t(sympos, ofile); - fwriteint32_t(nsyms + initsym, ofile); - fwriteint16_t(0, ofile); /* no optional header */ + i = IMAGE_FILE_MACHINE_I386; + fwriteint16_t(i, ofile); /* machine type */ + fwriteint16_t(nsects, ofile); /* number of sections */ + fwriteint32_t(time(NULL), ofile); /* time stamp */ + fwriteint32_t(sympos, ofile); + fwriteint32_t(nsyms + initsym, ofile); + fwriteint16_t(0, ofile); /* no optional header */ /* Flags: 32-bit, no line numbers. Win32 doesn't even bother with them. */ fwriteint16_t((win32 | win64) ? 0 : 0x104, ofile); @@ -915,15 +927,16 @@ static void coff_section_header(char *name, int32_t vsize, memset(padname, 0, 8); strncpy(padname, name, 8); fwrite(padname, 8, 1, ofile); - fwriteint32_t(0, ofile); /* Virtual size field - set to 0 or vsize */ - fwriteint32_t(0L, ofile); /* RVA/offset - we ignore */ - fwriteint32_t(datalen, ofile); - fwriteint32_t(datapos, ofile); - fwriteint32_t(relpos, ofile); - fwriteint32_t(0L, ofile); /* no line numbers - we don't do 'em */ - fwriteint16_t(nrelocs, ofile); - fwriteint16_t(0, ofile); /* again, no line numbers */ - fwriteint32_t(flags, ofile); + + fwriteint32_t(0, ofile); /* Virtual size field - set to 0 or vsize */ + fwriteint32_t(0L, ofile); /* RVA/offset - we ignore */ + fwriteint32_t(datalen, ofile); + fwriteint32_t(datapos, ofile); + fwriteint32_t(relpos, ofile); + fwriteint32_t(0L, ofile); /* no line numbers - we don't do 'em */ + fwriteint16_t(nrelocs, ofile); + fwriteint16_t(0, ofile); /* again, no line numbers */ + fwriteint32_t(flags, ofile); } static void coff_write_relocs(struct Section *s) @@ -933,10 +946,10 @@ static void coff_write_relocs(struct Section *s) for (r = s->head; r; r = r->next) { fwriteint32_t(r->address, ofile); fwriteint32_t(r->symbol + (r->symbase == REAL_SYMBOLS ? initsym : - r->symbase == ABS_SYMBOL ? initsym - 1 : - r->symbase == SECT_SYMBOLS ? 2 : 0), - ofile); - fwriteint16_t(r->type, ofile); + r->symbase == ABS_SYMBOL ? initsym - 1 : + r->symbase == SECT_SYMBOLS ? 2 : 0), + ofile); + fwriteint16_t(r->type, ofile); } } @@ -953,9 +966,11 @@ static void coff_symbol(char *name, int32_t strpos, int32_t value, fwriteint32_t(0, ofile); fwriteint32_t(strpos, ofile); } - fwriteint32_t(value, ofile); - fwriteint16_t(section, ofile); - fwriteint16_t(type, ofile); + + fwriteint32_t(value, ofile); + fwriteint16_t(section, ofile); + fwriteint16_t(type, ofile); + fputc(storageclass, ofile); fputc(aux, ofile); } @@ -980,8 +995,8 @@ static void coff_write_symbols(void) for (i = 0; i < (uint32_t) nsects; i++) { coff_symbol(sects[i]->name, 0L, 0L, i + 1, 0, 3, 1); - fwriteint32_t(sects[i]->len, ofile); - fwriteint16_t(sects[i]->nrelocs, ofile); + fwriteint32_t(sects[i]->len, ofile); + fwriteint16_t(sects[i]->nrelocs,ofile); fwrite(filename, 12, 1, ofile); } @@ -1055,7 +1070,7 @@ static int coff_set_info(enum geninfo type, char **val) (void)val; return 0; } -#endif /* defined(OF_COFF) || defined(OF_WIN32) */ +#endif /* defined(OF_COFF) || defined(OF_WIN32) */ #ifdef OF_COFF -- cgit v1.2.1