head 1.9; access; symbols pkgsrc-2013Q2:1.9.0.16 pkgsrc-2013Q2-base:1.9 pkgsrc-2012Q4:1.9.0.14 pkgsrc-2012Q4-base:1.9 pkgsrc-2011Q4:1.9.0.12 pkgsrc-2011Q4-base:1.9 pkgsrc-2011Q2:1.9.0.10 pkgsrc-2011Q2-base:1.9 pkgsrc-2009Q4:1.9.0.8 pkgsrc-2009Q4-base:1.9 pkgsrc-2008Q4:1.9.0.6 pkgsrc-2008Q4-base:1.9 pkgsrc-2008Q3:1.9.0.4 pkgsrc-2008Q3-base:1.9 cube-native-xorg:1.9.0.2 cube-native-xorg-base:1.9 pkgsrc-2008Q2:1.8.0.4 pkgsrc-2008Q2-base:1.8 cwrapper:1.8.0.2 pkgsrc-2008Q1:1.7.0.2 pkgsrc-2008Q1-base:1.7 pkgsrc-2007Q4:1.5.0.8 pkgsrc-2007Q4-base:1.5 pkgsrc-2007Q3:1.5.0.6 pkgsrc-2007Q3-base:1.5 pkgsrc-2007Q2:1.5.0.4 pkgsrc-2007Q2-base:1.5 pkgsrc-2007Q1:1.5.0.2 pkgsrc-2007Q1-base:1.5 pkgsrc-2006Q4:1.2.0.16 pkgsrc-2006Q4-base:1.2 pkgsrc-2006Q3:1.2.0.14 pkgsrc-2006Q3-base:1.2 pkgsrc-2006Q2:1.2.0.12 pkgsrc-2006Q2-base:1.2 pkgsrc-2006Q1:1.2.0.10 pkgsrc-2006Q1-base:1.2 pkgsrc-2005Q4:1.2.0.8 pkgsrc-2005Q4-base:1.2 pkgsrc-2005Q3:1.2.0.6 pkgsrc-2005Q3-base:1.2 pkgsrc-2005Q2:1.2.0.4 pkgsrc-2005Q2-base:1.2 pkgsrc-2005Q1:1.2.0.2 pkgsrc-2005Q1-base:1.2 pkgsrc-2004Q4:1.1.0.2; locks; strict; comment @# @; 1.9 date 2008.09.07.14.09.40; author wiz; state dead; branches; next 1.8; 1.8 date 2008.06.17.14.06.25; author tron; state Exp; branches; next 1.7; 1.7 date 2008.01.28.05.38.20; author bjs; state dead; branches 1.7.2.1; next 1.6; 1.6 date 2008.01.05.21.49.42; author rillig; state Exp; branches; next 1.5; 1.5 date 2007.01.08.13.36.28; author jmmv; state Exp; branches; next 1.4; 1.4 date 2007.01.08.13.21.43; author jmmv; state Exp; branches; next 1.3; 1.3 date 2007.01.06.15.11.58; author jmmv; state Exp; branches; next 1.2; 1.2 date 2005.02.25.13.41.24; author tron; state dead; branches; next 1.1; 1.1 date 2005.01.06.13.06.10; author adrianp; state Exp; branches 1.1.2.1; next ; 1.7.2.1 date 2008.06.29.10.25.43; author rtr; state Exp; branches; next ; 1.1.2.1 date 2005.01.06.13.06.10; author salo; state dead; branches; next 1.1.2.2; 1.1.2.2 date 2005.01.07.01.40.27; author salo; state Exp; branches; next ; desc @@ 1.9 log @Update to 2.03.01: 2.03.01 ------- * Fix buffer overflow in the listing module. * Fix the handling of hexadecimal escape codes in `...` strings. * The Postscript/PDF documentation has been reformatted. * The -F option now implies -g. 2.03 ---- * Add support for Intel AVX, CLMUL and FMA instructions, including YMM registers. * "dy", "resy" and "yword" for 32-byte operands. * Fix some SSE5 instructions. * Intel INVEPT, INVVPID and MOVBE instructions. * Fix checking for critical expressions when the optimizer is enabled. * Support the DWARF debugging format for ELF targets. * Fix optimizations of signed bytes. * Fix operation on bigendian machines. * Fix buffer overflow in the preprocessor. * SAFESEH support for Win32, IMAGEREL for Win64 (SEH). * %? and %?? to refer to the name of a macro itself. In particular, "%idefine keyword $%?" can be used to make a keyword "disappear". * New options for dependency generation: -MD, -MF, -MP, -MT, -MQ. * New preprocessor directives %pathsearch and %depend; INCBIN reimplemented as a macro. * %include now resolves macros in a sane manner. * %substr can now be used to get other than one-character substrings. * New type of character/string constants, using backquotes (`...`), which support C-style escape sequences. * %defstr and %idefstr to stringize macro definitions before creation. * Fix forward references used in EQU statements. @ text @$NetBSD: patch-ad,v 1.8 2008/06/17 14:06:25 tron Exp $ --- preproc.c.orig 2008-02-19 19:08:57.000000000 +0000 +++ preproc.c 2008-06-17 15:01:56.000000000 +0100 @@@@ -1074,7 +1074,7 @@@@ } for (r = p, s = ourcopy; *r; r++) { - if (r > p+MAX_KEYWORD) + if (r >= p+MAX_KEYWORD) return tokval->t_type = TOKEN_ID; /* Not a keyword */ *s++ = tolower(*r); } @ 1.8 log @Add a patch from the "nasm" GIT repository to fix a crash triggered by certain assembler files. This closes the security hole reported in SA30594 (which is IMHO highly debatable). @ text @d1 1 a1 1 $NetBSD$ @ 1.7 log @ Update to version 2.01. There are far too many changes to include here; please see the ChangeLog if interested. All patches except Makefile patches are no longer necessary. While here, add -Wno-signed-char to quiet these warnings. Also change INSTALLATION_DIRS to AUTO_MKDIRS, quiet pkglint by setting INFO_FILES=yes. @ text @d1 1 a1 1 $NetBSD: patch-ad,v 1.6 2008/01/05 21:49:42 rillig Exp $ d3 11 a13 1322 --- /dev/null 2007-01-06 13:50:40.000000000 +0100 +++ output/outmacho.c 2006-02-02 22:50:47.000000000 +0100 @@@@ -0,0 +1,1319 @@@@ +/* outmacho.c output routines for the Netwide Assembler to produce + * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files + * + * The Netwide Assembler is copyright (C) 1996 Simon Tatham and + * Julian Hall. All rights reserved. The software is + * redistributable under the licence given in the file "Licence" + * distributed in the NASM archive. + */ + +/* Most of this file is, like Mach-O itself, based on a.out. For more + * guidelines see outaout.c. */ + +#include +#include +#include +#include + +#include "nasm.h" +#include "nasmlib.h" +#include "outform.h" + +#if defined(OF_MACHO) + +/* Mach-O in-file header structure sizes */ +#define MACHO_HEADER_SIZE (28) +#define MACHO_SEGCMD_SIZE (56) +#define MACHO_SECTCMD_SIZE (68) +#define MACHO_SYMCMD_SIZE (24) +#define MACHO_NLIST_SIZE (12) +#define MACHO_RELINFO_SIZE (8) + +/* Mach-O file header values */ +#define MH_MAGIC (0xfeedface) +#define CPU_TYPE_I386 (7) /* x86 platform */ +#define CPU_SUBTYPE_I386_ALL (3) /* all-x86 compatible */ +#define MH_OBJECT (0x1) /* object file */ + +#define LC_SEGMENT (0x1) /* segment load command */ +#define LC_SYMTAB (0x2) /* symbol table load command */ + +#define VM_PROT_NONE (0x00) +#define VM_PROT_READ (0x01) +#define VM_PROT_WRITE (0x02) +#define VM_PROT_EXECUTE (0x04) + +#define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE) +#define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE) + +struct section { + /* nasm internal data */ + struct section *next; + struct SAA *data; + long index; + struct reloc *relocs; + int align; + + /* data that goes into the file */ + char sectname[16]; /* what this section is called */ + char segname[16]; /* segment this section will be in */ + unsigned long size; /* in-memory and -file size */ + unsigned long nreloc; /* relocation entry count */ + unsigned long flags; /* type and attributes (masked) */ +}; + +#define SECTION_TYPE 0x000000ff /* section type mask */ + +#define S_REGULAR (0x0) /* standard section */ +#define S_ZEROFILL (0x1) /* zerofill, in-memory only */ + +#define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ +#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some + machine instructions */ +#define S_ATTR_EXT_RELOC 0x00000200 /* section has external + relocation entries */ +#define S_ATTR_LOC_RELOC 0x00000100 /* section has local + relocation entries */ + + +static struct sectmap { + const char *nasmsect; + const char *segname; + const char *sectname; + const long flags; +} sectmap[] = { { +".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS}, { +".data", "__DATA", "__data", S_REGULAR}, { +".rodata", "__DATA", "__const", S_REGULAR}, { +".bss", "__DATA", "__bss", S_ZEROFILL}, { +NULL, NULL, NULL}}; + +struct reloc { + /* nasm internal data */ + struct reloc *next; + + /* data that goes into the file */ + long addr; /* op's offset in section */ + unsigned int snum:24, /* contains symbol index if + ** ext otherwise in-file + ** section number */ + pcrel:1, /* relative relocation */ + length:2, /* 0=byte, 1=word, 2=long */ + ext:1, /* external symbol referenced */ + type:4; /* reloc type, 0 for us */ +}; + +#define R_ABS 0 /* absolute relocation */ +#define R_SCATTERED 0x80000000 /* reloc entry is scattered if + ** highest bit == 1 */ + +struct symbol { + /* nasm internal data */ + struct symbol *next; /* next symbol in the list */ + char *name; /* name of this symbol */ + long initial_snum; /* symbol number used above in + reloc */ + long snum; /* true snum for reloc */ + + /* data that goes into the file */ + long strx; /* string table index */ + unsigned char type; /* symbol type */ + unsigned char sect; /* NO_SECT or section number */ + short desc; /* for stab debugging, 0 for us */ + unsigned long value; /* offset of symbol in section */ +}; + +/* symbol type bits */ +#define N_EXT 0x01 /* global or external symbol */ + +#define N_UNDF 0x0 /* undefined symbol | n_sect == */ +#define N_ABS 0x2 /* absolute symbol | NO_SECT */ +#define N_SECT 0xe /* defined symbol, n_sect holds + ** section number */ + +#define N_TYPE 0x0e /* type bit mask */ + +#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */ + +/* special section number values */ +#define NO_SECT 0 /* no section, invalid */ +#define MAX_SECT 255 /* maximum number of sections */ + +static struct section *sects, **sectstail; +static struct symbol *syms, **symstail; +static unsigned long nsyms; + +/* These variables are set by macho_layout_symbols() to organize + the symbol table and string table in order the dynamic linker + expects. They are then used in macho_write() to put out the + symbols and strings in that order. + + The order of the symbol table is: + local symbols + defined external symbols (sorted by name) + undefined external symbols (sorted by name) + + The order of the string table is: + strings for external symbols + strings for local symbols + */ +static unsigned long ilocalsym = 0; +static unsigned long iextdefsym = 0; +static unsigned long iundefsym = 0; +static unsigned long nlocalsym; +static unsigned long nextdefsym; +static unsigned long nundefsym; +static struct symbol **extdefsyms = NULL; +static struct symbol **undefsyms = NULL; + +static struct RAA *extsyms; +static struct SAA *strs; +static unsigned long strslen; + +static FILE *machofp; +static efunc error; +static evalfunc evaluate; + +extern struct ofmt of_macho; + +/* Global file information. This should be cleaned up into either + a structure or as function arguments. */ +unsigned long head_ncmds = 0; +unsigned long head_sizeofcmds = 0; +unsigned long seg_filesize = 0; +unsigned long seg_vmsize = 0; +unsigned long seg_nsects = 0; +unsigned long rel_padcnt = 0; + + +#define xstrncpy(xdst, xsrc) \ + memset(xdst, '\0', sizeof(xdst)); /* zero out whole buffer */ \ + strncpy(xdst, xsrc, sizeof(xdst)); /* copy over string */ \ + xdst[sizeof(xdst) - 1] = '\0'; /* proper null-termination */ + +#define align(x, y) \ + (((x) + (y) - 1) & ~((y) - 1)) /* align x to multiple of y */ + +#define alignlong(x) \ + align(x, sizeof(long)) /* align x to long boundary */ + +static void debug_reloc (struct reloc *); +static void debug_section_relocs (struct section *) __attribute__ ((unused)); + +static int exact_log2 (unsigned long align) { + if (align != (align & -align)) { + return -1; + } else { +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GCC_MINOR__ >= 4) + return (align ? __builtin_ctzl (align) : 0); +#else + unsigned long result = 0; + + while (align >>= 1) { + ++result; + } + + return result; +#endif + } +} + +static struct section *get_section_by_name(const char *segname, + const char *sectname) +{ + struct section *s; + + for (s = sects; s != NULL; s = s->next) + if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname)) + break; + + return s; +} + +static struct section *get_section_by_index(const long index) +{ + struct section *s; + + for (s = sects; s != NULL; s = s->next) + if (index == s->index) + break; + + return s; +} + +static long get_section_index_by_name(const char *segname, + const char *sectname) +{ + struct section *s; + + for (s = sects; s != NULL; s = s->next) + if (!strcmp(s->segname, segname) && !strcmp(s->sectname, sectname)) + return s->index; + + return -1; +} + +static char *get_section_name_by_index(const long index) +{ + struct section *s; + + for (s = sects; s != NULL; s = s->next) + if (index == s->index) + return s->sectname; + + return NULL; +} + +static unsigned char get_section_fileindex_by_index(const long index) +{ + struct section *s; + unsigned char i = 1; + + for (s = sects; s != NULL && i < MAX_SECT; s = s->next, ++i) + if (index == s->index) + return i; + + if (i == MAX_SECT) + error(ERR_WARNING, + "too many sections (>255) - clipped by fileindex"); + + return NO_SECT; +} + +static void macho_init(FILE * fp, efunc errfunc, ldfunc ldef, + evalfunc eval) +{ + char zero = 0; + + machofp = fp; + error = errfunc; + evaluate = eval; + + (void)ldef; /* placate optimisers */ + + sects = NULL; + sectstail = §s; + + syms = NULL; + symstail = &syms; + nsyms = 0; + nlocalsym = 0; + nextdefsym = 0; + nundefsym = 0; + + extsyms = raa_init(); + strs = saa_init(1L); + + /* string table starts with a zero byte - don't ask why */ + saa_wbytes(strs, &zero, sizeof(char)); + strslen = 1; +} + +static int macho_setinfo(enum geninfo type, char **val) +{ + return 0; +} + +static void sect_write(struct section *sect, + const unsigned char *data, unsigned long len) +{ + saa_wbytes(sect->data, data, len); + sect->size += len; +} + +static void add_reloc(struct section *sect, long section, + int pcrel, int bytes) +{ + struct reloc *r; + long fi; + + /* NeXT as puts relocs in reversed order (address-wise) into the + ** files, so we do the same, doesn't seem to make much of a + ** difference either way */ + r = nasm_malloc(sizeof(struct reloc)); + r->next = sect->relocs; + sect->relocs = r; + + /* the current end of the section will be the symbol's address for + ** now, might have to be fixed by macho_fixup_relocs() later on. make + ** sure we don't make the symbol scattered by setting the highest + ** bit by accident */ + r->addr = sect->size & ~R_SCATTERED; + r->ext = 0; + r->pcrel = pcrel; + + /* match byte count 1, 2, 4 to length codes 0, 1, 2 respectively */ + r->length = bytes >> 1; + + /* vanilla relocation (GENERIC_RELOC_VANILLA) */ + r->type = 0; + + if (section == NO_SEG) { + /* absolute local symbol if no section index given */ + r->snum = R_ABS; + } else { + fi = get_section_fileindex_by_index(section); + + if (fi == NO_SECT) { + /* external symbol if no section with that index known, + ** symbol number was saved in macho_symdef() */ + r->snum = raa_read(extsyms, section); + r->ext = 1; + } else { + /* local symbol in section fi */ + r->snum = fi; + } + } + + ++sect->nreloc; +} + +static void macho_output(long secto, const void *data, unsigned long type, + long section, long wrt) +{ + struct section *s, *sbss; + long realbytes = type & OUT_SIZMASK; + long addr; + unsigned char mydata[4], *p; + + type &= OUT_TYPMASK; + + if (wrt != NO_SEG) { + wrt = NO_SEG; + error(ERR_NONFATAL, "WRT not supported by Mach-O output format"); + /* continue to do _something_ */ + } + + if (secto == NO_SEG) { + if (type != OUT_RESERVE) + error(ERR_NONFATAL, "attempt to assemble code in " + "[ABSOLUTE] space"); + + return; + } + + s = get_section_by_index(secto); + + if (s == NULL) { + error(ERR_WARNING, "attempt to assemble code in" + " section %d: defaulting to `.text'", secto); + s = get_section_by_name("__TEXT", "__text"); + + /* should never happen */ + if (s == NULL) + error(ERR_PANIC, "text section not found"); + } + + sbss = get_section_by_name("__DATA", "__bss"); + + if (s == sbss && type != OUT_RESERVE) { + error(ERR_WARNING, "attempt to initialise memory in the" + " BSS section: ignored"); + + switch (type) { + case OUT_REL2ADR: + realbytes = 2; + break; + + case OUT_REL4ADR: + realbytes = 4; + break; + + default: + break; + } + + s->size += realbytes; + return; + } + + switch (type) { + case OUT_RESERVE: + if (s != sbss) { + error(ERR_WARNING, "uninitialised space declared in" + " %s section: zeroing", + get_section_name_by_index(secto)); + + sect_write(s, NULL, realbytes); + } else + s->size += realbytes; + + break; + + case OUT_RAWDATA: + if (section != NO_SEG) + error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG"); + + sect_write(s, data, realbytes); + break; + + case OUT_ADDRESS: + addr = *(long *)data; + + if (section != NO_SEG) { + if (section % 2) { + error(ERR_NONFATAL, "Mach-O format does not support" + " section base references"); + } else + add_reloc(s, section, 0, realbytes); + } + + p = mydata; + + if (realbytes == 2) + WRITESHORT(p, addr); + else + WRITELONG(p, addr); + + sect_write(s, mydata, realbytes); + break; + + case OUT_REL2ADR: + if (section == secto) + error(ERR_PANIC, "intra-section OUT_REL2ADR"); + + if (section != NO_SEG && section % 2) { + error(ERR_NONFATAL, "Mach-O format does not support" + " section base references"); + } else + add_reloc(s, section, 1, 2); + + p = mydata; + WRITESHORT(p, *(long *)data - (realbytes + s->size)); + sect_write(s, mydata, 2L); + break; + + case OUT_REL4ADR: + if (section == secto) + error(ERR_PANIC, "intra-section OUT_REL4ADR"); + + if (section != NO_SEG && section % 2) { + error(ERR_NONFATAL, "Mach-O format does not support" + " section base references"); + } else + add_reloc(s, section, 1, 4); + + p = mydata; + WRITELONG(p, *(long *)data - (realbytes + s->size)); + sect_write(s, mydata, 4L); + break; + + default: + error(ERR_PANIC, "unknown output type?"); + break; + } +} + +static long macho_section(char *name, int pass, int *bits) +{ + long index, originalIndex; + char *sectionAttributes; + struct sectmap *sm; + struct section *s; + + /* Default to 32 bits. */ + if (!name) { + *bits = 32; + name = ".text"; + sectionAttributes = NULL; + } else { + sectionAttributes = name; + name = strsep(§ionAttributes, " \t"); + } + + for (sm = sectmap; sm->nasmsect != NULL; ++sm) { + /* make lookup into section name translation table */ + if (!strcmp(name, sm->nasmsect)) { + char *currentAttribute; + + /* try to find section with that name */ + originalIndex = index = get_section_index_by_name(sm->segname, + sm->sectname); + + /* create it if it doesn't exist yet */ + if (index == -1) { + s = *sectstail = nasm_malloc(sizeof(struct section)); + s->next = NULL; + sectstail = &s->next; + + s->data = saa_init(1L); + s->index = seg_alloc(); + s->relocs = NULL; + s->align = DEFAULT_SECTION_ALIGNMENT; + + xstrncpy(s->segname, sm->segname); + xstrncpy(s->sectname, sm->sectname); + s->size = 0; + s->nreloc = 0; + s->flags = sm->flags; + + index = s->index; + } else { + s = get_section_by_index(index); + } + + while ((NULL != sectionAttributes) + && (currentAttribute = strsep(§ionAttributes, " \t"))) { + if (0 != *currentAttribute) { + if (0 == strncasecmp("align=", currentAttribute, 6)) { + char *end; + int newAlignment, value; + + value = strtoul(currentAttribute + 6, &end, 0); + newAlignment = exact_log2(value); + + if (0 != *end) { + error(ERR_PANIC, + "unknown or missing alignment value \"%s\" " + "specified for section \"%s\"", + currentAttribute + 6, + name); + return NO_SEG; + } else if (0 > newAlignment) { + error(ERR_PANIC, + "alignment of %d (for section \"%s\") is not " + "a power of two", + value, + name); + return NO_SEG; + } + + if ((-1 != originalIndex) + && (s->align != newAlignment)) { + error(ERR_PANIC, + "section \"%s\" has already been specified " + "with alignment %d, conflicts with new " + "alignment of %d", + name, + (1 << s->align), + value); + return NO_SEG; + } + + s->align = newAlignment; + } else if (0 == strcasecmp("data", currentAttribute)) { + /* Do nothing; 'data' is implicit */ + } else { + error(ERR_PANIC, + "unknown section attribute %s for section %s", + currentAttribute, + name); + return NO_SEG; + } + } + } + + return index; + } + } + + error(ERR_PANIC, "invalid section name %s", name); + return NO_SEG; +} + +static void macho_symdef(char *name, long section, long offset, + int is_global, char *special) +{ + struct symbol *sym; + + if (special) { + error(ERR_NONFATAL, "The Mach-O output format does " + "not support any special symbol types"); + return; + } + + if (is_global == 3) { + error(ERR_NONFATAL, "The Mach-O format does not " + "(yet) support forward reference fixups."); + return; + } + + sym = *symstail = nasm_malloc(sizeof(struct symbol)); + sym->next = NULL; + symstail = &sym->next; + + sym->name = name; + sym->strx = strslen; + sym->type = 0; + sym->desc = 0; + sym->value = offset; + sym->initial_snum = -1; + + /* external and common symbols get N_EXT */ + if (is_global != 0) + sym->type |= N_EXT; + + if (section == NO_SEG) { + /* symbols in no section get absolute */ + sym->type |= N_ABS; + sym->sect = NO_SECT; + } else { + sym->type |= N_SECT; + + /* get the in-file index of the section the symbol was defined in */ + sym->sect = get_section_fileindex_by_index(section); + + if (sym->sect == NO_SECT) { + /* remember symbol number of references to external + ** symbols, this works because every external symbol gets + ** its own section number allocated internally by nasm and + ** can so be used as a key */ + extsyms = raa_write(extsyms, section, nsyms); + sym->initial_snum = nsyms; + + switch (is_global) { + case 1: + case 2: + /* there isn't actually a difference between global + ** and common symbols, both even have their size in + ** sym->value */ + sym->type = N_EXT; + break; + + default: + /* give an error on unfound section if it's not an + ** external or common symbol (assemble_file() does a + ** seg_alloc() on every call for them) */ + error(ERR_PANIC, "in-file index for section %d not found", + section); + } + } + } + + ++nsyms; +} + +static long macho_segbase(long section) +{ + return section; +} + +static int macho_directive(char *directive, char *value, int pass) +{ + return 0; +} + +static void macho_filename(char *inname, char *outname, efunc error) +{ + standard_extension(inname, outname, ".o", error); +} + +static const char *macho_stdmac[] = { + "%define __SECT__ [section .text]", + "%macro __NASM_CDecl__ 1", + "%endmacro", + NULL +}; + +/* Comparison function for qsort symbol layout. */ +static int layout_compare (const struct symbol **s1, + const struct symbol **s2) +{ + return (strcmp ((*s1)->name, (*s2)->name)); +} + +/* The native assembler does a few things in a similar function + + * Remove temporary labels + * Sort symbols according to local, external, undefined (by name) + * Order the string table + + We do not remove temporary labels right now. + + numsyms is the total number of symbols we have. strtabsize is the + number entries in the string table. */ + +static void macho_layout_symbols (unsigned long *numsyms, + unsigned long *strtabsize) +{ + struct symbol *sym, **symp; + unsigned long i,j; + + *numsyms = 0; + *strtabsize = sizeof (char); + + symp = &syms; + + while ((sym = *symp)) { + /* Undefined symbols are now external. */ + if (sym->type == N_UNDF) + sym->type |= N_EXT; + + if ((sym->type & N_EXT) == 0) { + sym->snum = *numsyms; + *numsyms = *numsyms + 1; + nlocalsym++; + } + else { + if ((sym->type & N_TYPE) != N_UNDF) + nextdefsym++; + else + nundefsym++; + + /* If we handle debug info we'll want + to check for it here instead of just + adding the symbol to the string table. */ + sym->strx = *strtabsize; + saa_wbytes (strs, sym->name, (long)(strlen(sym->name) + 1)); + *strtabsize += strlen(sym->name) + 1; + } + symp = &(sym->next); + } + + /* Next, sort the symbols. Most of this code is a direct translation from + the Apple cctools symbol layout. We need to keep compatibility with that. */ + /* Set the indexes for symbol groups into the symbol table */ + ilocalsym = 0; + iextdefsym = nlocalsym; + iundefsym = nlocalsym + nextdefsym; + + /* allocate arrays for sorting externals by name */ + extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *)); + undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *)); + + i = 0; + j = 0; + + symp = &syms; + + while ((sym = *symp)) { + + if((sym->type & N_EXT) == 0) { + sym->strx = *strtabsize; + saa_wbytes (strs, sym->name, (long)(strlen (sym->name) + 1)); + *strtabsize += strlen(sym->name) + 1; + } + else { + if((sym->type & N_TYPE) != N_UNDF) + extdefsyms[i++] = sym; + else + undefsyms[j++] = sym; + } + symp = &(sym->next); + } + + qsort(extdefsyms, nextdefsym, sizeof(struct symbol *), + (int (*)(const void *, const void *))layout_compare); + qsort(undefsyms, nundefsym, sizeof(struct symbol *), + (int (*)(const void *, const void *))layout_compare); + + for(i = 0; i < nextdefsym; i++) { + extdefsyms[i]->snum = *numsyms; + *numsyms += 1; + } + for(j = 0; j < nundefsym; j++) { + undefsyms[j]->snum = *numsyms; + *numsyms += 1; + } +} + +/* Calculate some values we'll need for writing later. */ + +static void macho_calculate_sizes (void) +{ + struct section *s; + + /* count sections and calculate in-memory and in-file offsets */ + for (s = sects; s != NULL; s = s->next) { + /* zerofill sections aren't actually written to the file */ + if ((s->flags & SECTION_TYPE) != S_ZEROFILL) + seg_filesize += s->size; + + seg_vmsize += s->size; + ++seg_nsects; + } + + /* calculate size of all headers, load commands and sections to + ** get a pointer to the start of all the raw data */ + if (seg_nsects > 0) { + ++head_ncmds; + head_sizeofcmds += + MACHO_SEGCMD_SIZE + seg_nsects * MACHO_SECTCMD_SIZE; + } + + if (nsyms > 0) { + ++head_ncmds; + head_sizeofcmds += MACHO_SYMCMD_SIZE; + } +} + +/* Write out the header information for the file. */ + +static void macho_write_header (void) +{ + fwritelong(MH_MAGIC, machofp); /* magic */ + fwritelong(CPU_TYPE_I386, machofp); /* CPU type */ + fwritelong(CPU_SUBTYPE_I386_ALL, machofp); /* CPU subtype */ + fwritelong(MH_OBJECT, machofp); /* Mach-O file type */ + fwritelong(head_ncmds, machofp); /* number of load commands */ + fwritelong(head_sizeofcmds, machofp); /* size of load commands */ + fwritelong(0, machofp); /* no flags */ +} + +/* Write out the segment load command at offset. */ + +static unsigned long macho_write_segment (unsigned long offset) +{ + unsigned long s_addr = 0; + unsigned long rel_base = alignlong (offset + seg_filesize); + unsigned long s_reloff = 0; + struct section *s; + + fwritelong(LC_SEGMENT, machofp); /* cmd == LC_SEGMENT */ + + /* size of load command including section load commands */ + fwritelong(MACHO_SEGCMD_SIZE + seg_nsects * + MACHO_SECTCMD_SIZE, machofp); + + /* in an MH_OBJECT file all sections are in one unnamed (name + ** all zeros) segment */ + fwrite("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16, 1, machofp); + fwritelong(0, machofp); /* in-memory offset */ + fwritelong(seg_vmsize, machofp); /* in-memory size */ + fwritelong(offset, machofp); /* in-file offset to data */ + fwritelong(seg_filesize, machofp); /* in-file size */ + fwritelong(VM_PROT_DEFAULT, machofp); /* maximum vm protection */ + fwritelong(VM_PROT_DEFAULT, machofp); /* initial vm protection */ + fwritelong(seg_nsects, machofp); /* number of sections */ + fwritelong(0, machofp); /* no flags */ + + /* emit section headers */ + for (s = sects; s != NULL; s = s->next) { + fwrite(s->sectname, sizeof(s->sectname), 1, machofp); + fwrite(s->segname, sizeof(s->segname), 1, machofp); + fwritelong(s_addr, machofp); + fwritelong(s->size, machofp); + + /* dummy data for zerofill sections or proper values */ + if ((s->flags & SECTION_TYPE) != S_ZEROFILL) { + fwritelong(offset, machofp); + /* Write out section alignment, as a power of two. + e.g. 32-bit word alignment would be 2 (2^^2 = 4). */ + fwritelong(s->align, machofp); + /* To be compatible with cctools as we emit + a zero reloff if we have no relocations. */ + fwritelong(s->nreloc ? rel_base + s_reloff : 0, machofp); + fwritelong(s->nreloc, machofp); + + offset += s->size; + s_reloff += s->nreloc * MACHO_RELINFO_SIZE; + } else { + fwritelong(0, machofp); + fwritelong(0, machofp); + fwritelong(0, machofp); + fwritelong(0, machofp); + } + + fwritelong(s->flags, machofp); /* flags */ + fwritelong(0, machofp); /* reserved */ + fwritelong(0, machofp); /* reserved */ + + s_addr += s->size; + } + + rel_padcnt = rel_base - offset; + offset = rel_base + s_reloff; + + return offset; +} + +/* For a given chain of relocs r, write out the entire relocation + chain to the object file. */ + +static void macho_write_relocs (struct reloc *r) +{ + while (r) { + unsigned long word2; + + fwritelong(r->addr, machofp); /* reloc offset */ + + word2 = r->snum; + word2 |= r->pcrel << 24; + word2 |= r->length << 25; + word2 |= r->ext << 27; + word2 |= r->type << 28; + fwritelong(word2, machofp); /* reloc data */ + + r = r->next; + } +} + +/* Write out the section data. */ +static void macho_write_section (void) +{ + struct section *s, *s2; + struct reloc *r; + char *rel_paddata = "\0\0\0"; + unsigned char fi, *p, *q, blk[4]; + long l; + + for (s = sects; s != NULL; s = s->next) { + if ((s->flags & SECTION_TYPE) == S_ZEROFILL) + continue; + + /* no padding needs to be done to the sections */ + + /* Like a.out Mach-O references things in the data or bss + * sections by addresses which are actually relative to the + * start of the _text_ section, in the _file_. See outaout.c + * for more information. */ + saa_rewind(s->data); + for (r = s->relocs; r != NULL; r = r->next) { + saa_fread(s->data, r->addr, blk, (long)r->length << 1); + p = q = blk; + l = *p++; + + /* get offset based on relocation type */ + if (r->length > 0) { + l += ((long)*p++) << 8; + + if (r->length == 2) { + l += ((long)*p++) << 16; + l += ((long)*p++) << 24; + } + } + + /* If the relocation is internal add to the current section + offset. Otherwise the only value we need is the symbol + offset which we already have. The linker takes care + of the rest of the address. */ + if (!r->ext) { + /* add sizes of previous sections to current offset */ + for (s2 = sects, fi = 1; + s2 != NULL && fi < r->snum; s2 = s2->next, fi++) + if ((s2->flags & SECTION_TYPE) != S_ZEROFILL) + l += s2->size; + } + + /* write new offset back */ + if (r->length == 2) + WRITELONG(q, l); + else if (r->length == 1) + WRITESHORT(q, l); + else + *q++ = l & 0xFF; + + saa_fwrite(s->data, r->addr, blk, (long)r->length << 1); + } + + /* dump the section data to file */ + saa_fpwrite(s->data, machofp); + } + + /* pad last section up to reloc entries on long boundary */ + fwrite(rel_paddata, rel_padcnt, 1, machofp); + + /* emit relocation entries */ + for (s = sects; s != NULL; s = s->next) + macho_write_relocs (s->relocs); +} + +/* Write out the symbol table. We should already have sorted this + before now. */ +static void macho_write_symtab (void) +{ + struct symbol *sym; + struct section *s; + long fi; + long i; + + /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */ + + for (sym = syms; sym != NULL; sym = sym->next) { + if ((sym->type & N_EXT) == 0) { + fwritelong(sym->strx, machofp); /* string table entry number */ + fwrite(&sym->type, 1, 1, machofp); /* symbol type */ + fwrite(&sym->sect, 1, 1, machofp); /* section */ + fwriteshort(sym->desc, machofp); /* description */ + + /* Fix up the symbol value now that we know the final section + sizes. */ + if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) { + for (s = sects, fi = 1; + s != NULL && fi < sym->sect; s = s->next, ++fi) + sym->value += s->size; + } + + fwritelong(sym->value, machofp); /* value (i.e. offset) */ + } + } + + for (i = 0; i < nextdefsym; i++) { + sym = extdefsyms[i]; + fwritelong(sym->strx, machofp); + fwrite(&sym->type, 1, 1, machofp); /* symbol type */ + fwrite(&sym->sect, 1, 1, machofp); /* section */ + fwriteshort(sym->desc, machofp); /* description */ + + /* Fix up the symbol value now that we know the final section + sizes. */ + if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) { + for (s = sects, fi = 1; + s != NULL && fi < sym->sect; s = s->next, ++fi) + sym->value += s->size; + } + + fwritelong(sym->value, machofp); /* value (i.e. offset) */ + } + + for (i = 0; i < nundefsym; i++) { + sym = undefsyms[i]; + fwritelong(sym->strx, machofp); + fwrite(&sym->type, 1, 1, machofp); /* symbol type */ + fwrite(&sym->sect, 1, 1, machofp); /* section */ + fwriteshort(sym->desc, machofp); /* description */ + + /* Fix up the symbol value now that we know the final section + sizes. */ + if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) { + for (s = sects, fi = 1; + s != NULL && fi < sym->sect; s = s->next, ++fi) + sym->value += s->size; + } + + fwritelong(sym->value, machofp); /* value (i.e. offset) */ + } +} + +/* Fixup the snum in the relocation entries, we should be + doing this only for externally undefined symbols. */ +static void macho_fixup_relocs (struct reloc *r) +{ + struct symbol *sym; + int i; + + while (r != NULL) { + if (r->ext) { + for (i = 0; i < nundefsym; i++) { + sym = undefsyms[i]; + if (sym->initial_snum == r->snum) { + r->snum = sym->snum; + } + } + } + r = r->next; + } +} + +/* Write out the object file. */ + +static void macho_write (void) +{ + unsigned long offset = 0; + + /* mach-o object file structure: + ** + ** mach header + ** ulong magic + ** int cpu type + ** int cpu subtype + ** ulong mach file type + ** ulong number of load commands + ** ulong size of all load commands + ** (includes section struct size of segment command) + ** ulong flags + ** + ** segment command + ** ulong command type == LC_SEGMENT + ** ulong size of load command + ** (including section load commands) + ** char[16] segment name + ** ulong in-memory offset + ** ulong in-memory size + ** ulong in-file offset to data area + ** ulong in-file size + ** (in-memory size excluding zerofill sections) + ** int maximum vm protection + ** int initial vm protection + ** ulong number of sections + ** ulong flags + ** + ** section commands + ** char[16] section name + ** char[16] segment name + ** ulong in-memory offset + ** ulong in-memory size + ** ulong in-file offset + ** ulong alignment + ** (irrelevant in MH_OBJECT) + ** ulong in-file offset of relocation entires + ** ulong number of relocations + ** ulong flags + ** ulong reserved + ** ulong reserved + ** + ** symbol table command + ** ulong command type == LC_SYMTAB + ** ulong size of load command + ** ulong symbol table offset + ** ulong number of symbol table entries + ** ulong string table offset + ** ulong string table size + ** + ** raw section data + ** + ** padding to long boundary + ** + ** relocation data (struct reloc) + ** long offset + ** uint data (symbolnum, pcrel, length, extern, type) + ** + ** symbol table data (struct nlist) + ** long string table entry number + ** uchar type + ** (extern, absolute, defined in section) + ** uchar section + ** (0 for global symbols, section number of definition (>= 1, <= + ** 254) for local symbols, size of variable for common symbols + ** [type == extern]) + ** short description + ** (for stab debugging format) + ** ulong value (i.e. file offset) of symbol or stab offset + ** + ** string table data + ** list of null-terminated strings + */ + + /* Emit the Mach-O header. */ + macho_write_header(); + + offset = MACHO_HEADER_SIZE + head_sizeofcmds; + + /* emit the segment load command */ + if (seg_nsects > 0) + offset = macho_write_segment (offset); + else + error(ERR_WARNING, "no sections?"); + + if (nsyms > 0) { + /* write out symbol command */ + fwritelong(LC_SYMTAB, machofp); /* cmd == LC_SYMTAB */ + fwritelong(MACHO_SYMCMD_SIZE, machofp); /* size of load command */ + fwritelong(offset, machofp); /* symbol table offset */ + fwritelong(nsyms, machofp); /* number of symbol + ** table entries */ + + offset += nsyms * MACHO_NLIST_SIZE; + fwritelong(offset, machofp); /* string table offset */ + fwritelong(strslen, machofp); /* string table size */ + } + + /* emit section data */ + if (seg_nsects > 0) + macho_write_section (); + + /* emit symbol table if we have symbols */ + if (nsyms > 0) + macho_write_symtab (); + + /* we don't need to pad here since MACHO_NLIST_SIZE == 12 */ + + /* emit string table */ + saa_fpwrite(strs, machofp); +} +/* We do quite a bit here, starting with finalizing all of the data + for the object file, writing, and then freeing all of the data from + the file. */ + +static void macho_cleanup(int debuginfo) +{ + struct section *s; + struct reloc *r; + struct symbol *sym; + + (void)debuginfo; + + /* Sort all symbols. */ + macho_layout_symbols (&nsyms, &strslen); + + /* Fixup relocation entries */ + for (s = sects; s != NULL; s = s->next) { + macho_fixup_relocs (s->relocs); + } + + /* First calculate and finalize needed values. */ + macho_calculate_sizes(); + macho_write(); + + /* done - yay! */ + fclose(machofp); + + /* free up everything */ + while (sects->next) { + s = sects; + sects = sects->next; + + saa_free(s->data); + while (s->relocs != NULL) { + r = s->relocs; + s->relocs = s->relocs->next; + nasm_free(r); + } + + nasm_free(s); + } + + saa_free(strs); + raa_free(extsyms); + + if (syms) { + while (syms->next) { + sym = syms; + syms = syms->next; + + nasm_free (sym); + } + } +} + +/* Debugging routines. */ +static void debug_reloc (struct reloc *r) +{ + fprintf (stdout, "reloc:\n"); + fprintf (stdout, "\taddr: %ld\n", r->addr); + fprintf (stdout, "\tsnum: %d\n", r->snum); + fprintf (stdout, "\tpcrel: %d\n", r->pcrel); + fprintf (stdout, "\tlength: %d\n", r->length); + fprintf (stdout, "\text: %d\n", r->ext); + fprintf (stdout, "\ttype: %d\n", r->type); +} + +static void debug_section_relocs (struct section *s) +{ + struct reloc *r = s->relocs; + + fprintf (stdout, "relocs for section %s:\n\n", s->sectname); + + while (r != NULL) { + debug_reloc (r); + r = r->next; + } +} + +struct ofmt of_macho = { + "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files", + "macho", + NULL, + null_debug_arr, + &null_debug_form, + macho_stdmac, + macho_init, + macho_setinfo, + macho_output, + macho_symdef, + macho_section, + macho_segbase, + macho_directive, + macho_filename, + macho_cleanup +}; + +#endif + +/* + * Local Variables: + * mode:c + * c-basic-offset:4 + * End: + * + * end of file */ @ 1.7.2.1 log @pullup ticket #2429 - requested by tron nasm: fixes bug in nasm which is a "possible" security issue revisions pulled up: pkgsrc/devel/nasm/Makefile 1.36 pkgsrc/devel/nasm/distinfo 1.16 pkgsrc/devel/nasm/patches/patch-ad 1.8 Module Name: pkgsrc Committed By: tron Date: Tue Jun 17 14:06:25 UTC 2008 Modified Files: pkgsrc/devel/nasm: Makefile distinfo Added Files: pkgsrc/devel/nasm/patches: patch-ad Log Message: Add a patch from the "nasm" GIT repository to fix a crash triggered by certain assembler files. This closes the security hole reported in SA30594 (which is IMHO highly debatable). @ text @d1 1 a1 1 $NetBSD: patch-ad,v 1.8 2008/06/17 14:06:25 tron Exp $ d3 1322 a1324 11 --- preproc.c.orig 2008-02-19 19:08:57.000000000 +0000 +++ preproc.c 2008-06-17 15:01:56.000000000 +0100 @@@@ -1074,7 +1074,7 @@@@ } for (r = p, s = ourcopy; *r; r++) { - if (r > p+MAX_KEYWORD) + if (r >= p+MAX_KEYWORD) return tokval->t_type = TOKEN_ID; /* Not a keyword */ *s++ = tolower(*r); } @ 1.6 log @Patch files start with the CVS Id. @ text @d1 1 a1 1 $NetBSD$ @ 1.5 log @Ah well, GCC_VERSION is only defined within gcc code. Use __GNUC__ and __GNUC_MINOR__ instead. Still checking for >= 3.4.0 though. @ text @d1 2 @ 1.4 log @Only use __builtin_ctzl if it is available; minimum gcc version number taken from http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00828.html, so I guess it is right. Should fix PR pkg/35380 by tron@@, which reports build failure under NetBSD 3.1/i386 (it worked in -current, though). @ text @d210 1 a210 1 +#if defined(__GNUC__) && GCC_VERSION >= 3004 @ 1.3 log @Add support to generate Mach-O objects (for Intel Macs). Code taken from the CVS repository, so it will be in the next public release of nasm. Bump PKGREVISION to 3. @ text @d210 1 a210 1 +#ifdef __GNUC__ @ 1.2 log @Remove obsolete patch files. @ text @d1 1322 a1322 185 $NetBSD: patch-ad,v 1.1 2005/01/06 13:06:10 adrianp Exp $ --- disasm.c.orig 2003-02-24 18:22:45.000000000 -0500 +++ disasm.c 2004-12-15 18:00:13.000000000 -0500 @@@@ -484,8 +484,8 @@@@ return data - origdata; } -long disasm (unsigned char *data, char *output, int segsize, long offset, - int autosync, unsigned long prefer) +long disasm (unsigned char *data, char *output, int outbufsize, int segsize, + long offset, int autosync, unsigned long prefer) { struct itemplate **p, **best_p; int length, best_length = 0; @@@@ -583,26 +583,26 @@@@ slen = 0; if (lock) - slen += sprintf(output+slen, "lock "); + slen += snprintf(output+slen, outbufsize-slen, "lock "); for (i = 0; i < ins.nprefix; i++) switch (ins.prefixes[i]) { - case P_REP: slen += sprintf(output+slen, "rep "); break; - case P_REPE: slen += sprintf(output+slen, "repe "); break; - case P_REPNE: slen += sprintf(output+slen, "repne "); break; - case P_A16: slen += sprintf(output+slen, "a16 "); break; - case P_A32: slen += sprintf(output+slen, "a32 "); break; - case P_O16: slen += sprintf(output+slen, "o16 "); break; - case P_O32: slen += sprintf(output+slen, "o32 "); break; + case P_REP: slen += snprintf(output+slen, outbufsize-slen, "rep "); break; + case P_REPE: slen += snprintf(output+slen, outbufsize-slen, "repe "); break; + case P_REPNE: slen += snprintf(output+slen, outbufsize-slen, "repne "); break; + case P_A16: slen += snprintf(output+slen, outbufsize-slen, "a16 "); break; + case P_A32: slen += snprintf(output+slen, outbufsize-slen, "a32 "); break; + case P_O16: slen += snprintf(output+slen, outbufsize-slen, "o16 "); break; + case P_O32: slen += snprintf(output+slen, outbufsize-slen, "o32 "); break; } for (i = 0; i < elements(ico); i++) if ((*p)->opcode == ico[i]) { - slen += sprintf(output+slen, "%s%s", icn[i], + slen += snprintf(output+slen, outbufsize-slen, "%s%s", icn[i], whichcond(ins.condition)); break; } if (i >= elements(ico)) - slen += sprintf(output+slen, "%s", insn_names[(*p)->opcode]); + slen += snprintf(output+slen, outbufsize-slen, "%s", insn_names[(*p)->opcode]); colon = FALSE; length += data - origdata; /* fix up for prefixes */ for (i=0; i<(*p)->operands; i++) { @@@@ -633,14 +633,14 @@@@ ins.oprs[i].basereg = whichreg ((*p)->opd[i], ins.oprs[i].basereg); if ( (*p)->opd[i] & TO ) - slen += sprintf(output+slen, "to "); - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "to "); + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[ins.oprs[i].basereg-EXPR_REG_START]); } else if (!(UNITY & ~(*p)->opd[i])) { output[slen++] = '1'; } else if ( (*p)->opd[i] & IMMEDIATE ) { if ( (*p)->opd[i] & BITS8 ) { - slen += sprintf(output+slen, "byte "); + slen += snprintf(output+slen, outbufsize-slen, "byte "); if (ins.oprs[i].segment & SEG_SIGNED) { if (ins.oprs[i].offset < 0) { ins.oprs[i].offset *= -1; @@@@ -649,17 +649,17 @@@@ output[slen++] = '+'; } } else if ( (*p)->opd[i] & BITS16 ) { - slen += sprintf(output+slen, "word "); + slen += snprintf(output+slen, outbufsize-slen, "word "); } else if ( (*p)->opd[i] & BITS32 ) { - slen += sprintf(output+slen, "dword "); + slen += snprintf(output+slen, outbufsize-slen, "dword "); } else if ( (*p)->opd[i] & NEAR ) { - slen += sprintf(output+slen, "near "); + slen += snprintf(output+slen, outbufsize-slen, "near "); } else if ( (*p)->opd[i] & SHORT ) { - slen += sprintf(output+slen, "short "); + slen += snprintf(output+slen, outbufsize-slen, "short "); } - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) { - slen += sprintf(output+slen, "[%s%s%s0x%lx]", + slen += snprintf(output+slen, outbufsize-slen, "[%s%s%s0x%lx]", (segover ? segover : ""), (segover ? ":" : ""), (ins.oprs[i].addr_size == 32 ? "dword " : @@@@ -669,30 +669,30 @@@@ } else if ( !(REGMEM & ~(*p)->opd[i]) ) { int started = FALSE; if ( (*p)->opd[i] & BITS8 ) - slen += sprintf(output+slen, "byte "); + slen += snprintf(output+slen, outbufsize-slen, "byte "); if ( (*p)->opd[i] & BITS16 ) - slen += sprintf(output+slen, "word "); + slen += snprintf(output+slen, outbufsize-slen, "word "); if ( (*p)->opd[i] & BITS32 ) - slen += sprintf(output+slen, "dword "); + slen += snprintf(output+slen, outbufsize-slen, "dword "); if ( (*p)->opd[i] & BITS64 ) - slen += sprintf(output+slen, "qword "); + slen += snprintf(output+slen, outbufsize-slen, "qword "); if ( (*p)->opd[i] & BITS80 ) - slen += sprintf(output+slen, "tword "); + slen += snprintf(output+slen, outbufsize-slen, "tword "); if ( (*p)->opd[i] & FAR ) - slen += sprintf(output+slen, "far "); + slen += snprintf(output+slen, outbufsize-slen, "far "); if ( (*p)->opd[i] & NEAR ) - slen += sprintf(output+slen, "near "); + slen += snprintf(output+slen, outbufsize-slen, "near "); output[slen++] = '['; if (ins.oprs[i].addr_size) - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", (ins.oprs[i].addr_size == 32 ? "dword " : ins.oprs[i].addr_size == 16 ? "word " : "")); if (segover) { - slen += sprintf(output+slen, "%s:", segover); + slen += snprintf(output+slen, outbufsize-slen, "%s:", segover); segover = NULL; } if (ins.oprs[i].basereg != -1) { - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[(ins.oprs[i].basereg - EXPR_REG_START)]); started = TRUE; @@@@ -700,11 +700,11 @@@@ if (ins.oprs[i].indexreg != -1) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[(ins.oprs[i].indexreg - EXPR_REG_START)]); if (ins.oprs[i].scale > 1) - slen += sprintf(output+slen, "*%d", ins.oprs[i].scale); + slen += snprintf(output+slen, outbufsize-slen, "*%d", ins.oprs[i].scale); started = TRUE; } if (ins.oprs[i].segment & SEG_DISP8) { @@@@ -713,20 +713,20 @@@@ ins.oprs[i].offset = - (signed char) ins.oprs[i].offset; sign = '-'; } - slen += sprintf(output+slen, "%c0x%lx", sign, + slen += snprintf(output+slen, outbufsize-slen, "%c0x%lx", sign, ins.oprs[i].offset); } else if (ins.oprs[i].segment & SEG_DISP16) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } else if (ins.oprs[i].segment & SEG_DISP32) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } output[slen++] = ']'; } else { - slen += sprintf(output+slen, "", i); + slen += snprintf(output+slen, outbufsize-slen, "", i); } } output[slen] = '\0'; @@@@ -741,8 +741,8 @@@@ return length; } -long eatbyte (unsigned char *data, char *output) +long eatbyte (unsigned char *data, char *output, int outbufsize) { - sprintf(output, "db 0x%02X", *data); + snprintf(output, outbufsize, "db 0x%02X", *data); return 1; } @ 1.1 log @Bump to nb1 for recent security issue: http://sourceforge.net/mailarchive/forum.php?thread_id=6166881&forum_id=4978 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-1287 @ text @d1 1 a1 1 $NetBSD$ @ 1.1.2.1 log @file patch-ad was added on branch pkgsrc-2004Q4 on 2005-01-06 13:06:10 +0000 @ text @d1 185 @ 1.1.2.2 log @Pullup ticket 211 - requested by Adrian Portelli security fix for nasm Module Name: pkgsrc Committed By: adrianp Date: Thu Jan 6 13:06:10 UTC 2005 Modified Files: pkgsrc/devel/nasm: Makefile distinfo Added Files: pkgsrc/devel/nasm/patches: patch-ac patch-ad patch-ae patch-af patch-ag patch-ah patch-ai Log Message: Bump to nb1 for recent security issue: http://sourceforge.net/mailarchive/forum.php?thread_id=6166881&forum_id=4978 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2004-1287 @ text @a0 185 $NetBSD: patch-ad,v 1.1.2.1 2005/01/07 01:40:27 salo Exp $ --- disasm.c.orig 2003-02-24 18:22:45.000000000 -0500 +++ disasm.c 2004-12-15 18:00:13.000000000 -0500 @@@@ -484,8 +484,8 @@@@ return data - origdata; } -long disasm (unsigned char *data, char *output, int segsize, long offset, - int autosync, unsigned long prefer) +long disasm (unsigned char *data, char *output, int outbufsize, int segsize, + long offset, int autosync, unsigned long prefer) { struct itemplate **p, **best_p; int length, best_length = 0; @@@@ -583,26 +583,26 @@@@ slen = 0; if (lock) - slen += sprintf(output+slen, "lock "); + slen += snprintf(output+slen, outbufsize-slen, "lock "); for (i = 0; i < ins.nprefix; i++) switch (ins.prefixes[i]) { - case P_REP: slen += sprintf(output+slen, "rep "); break; - case P_REPE: slen += sprintf(output+slen, "repe "); break; - case P_REPNE: slen += sprintf(output+slen, "repne "); break; - case P_A16: slen += sprintf(output+slen, "a16 "); break; - case P_A32: slen += sprintf(output+slen, "a32 "); break; - case P_O16: slen += sprintf(output+slen, "o16 "); break; - case P_O32: slen += sprintf(output+slen, "o32 "); break; + case P_REP: slen += snprintf(output+slen, outbufsize-slen, "rep "); break; + case P_REPE: slen += snprintf(output+slen, outbufsize-slen, "repe "); break; + case P_REPNE: slen += snprintf(output+slen, outbufsize-slen, "repne "); break; + case P_A16: slen += snprintf(output+slen, outbufsize-slen, "a16 "); break; + case P_A32: slen += snprintf(output+slen, outbufsize-slen, "a32 "); break; + case P_O16: slen += snprintf(output+slen, outbufsize-slen, "o16 "); break; + case P_O32: slen += snprintf(output+slen, outbufsize-slen, "o32 "); break; } for (i = 0; i < elements(ico); i++) if ((*p)->opcode == ico[i]) { - slen += sprintf(output+slen, "%s%s", icn[i], + slen += snprintf(output+slen, outbufsize-slen, "%s%s", icn[i], whichcond(ins.condition)); break; } if (i >= elements(ico)) - slen += sprintf(output+slen, "%s", insn_names[(*p)->opcode]); + slen += snprintf(output+slen, outbufsize-slen, "%s", insn_names[(*p)->opcode]); colon = FALSE; length += data - origdata; /* fix up for prefixes */ for (i=0; i<(*p)->operands; i++) { @@@@ -633,14 +633,14 @@@@ ins.oprs[i].basereg = whichreg ((*p)->opd[i], ins.oprs[i].basereg); if ( (*p)->opd[i] & TO ) - slen += sprintf(output+slen, "to "); - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "to "); + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[ins.oprs[i].basereg-EXPR_REG_START]); } else if (!(UNITY & ~(*p)->opd[i])) { output[slen++] = '1'; } else if ( (*p)->opd[i] & IMMEDIATE ) { if ( (*p)->opd[i] & BITS8 ) { - slen += sprintf(output+slen, "byte "); + slen += snprintf(output+slen, outbufsize-slen, "byte "); if (ins.oprs[i].segment & SEG_SIGNED) { if (ins.oprs[i].offset < 0) { ins.oprs[i].offset *= -1; @@@@ -649,17 +649,17 @@@@ output[slen++] = '+'; } } else if ( (*p)->opd[i] & BITS16 ) { - slen += sprintf(output+slen, "word "); + slen += snprintf(output+slen, outbufsize-slen, "word "); } else if ( (*p)->opd[i] & BITS32 ) { - slen += sprintf(output+slen, "dword "); + slen += snprintf(output+slen, outbufsize-slen, "dword "); } else if ( (*p)->opd[i] & NEAR ) { - slen += sprintf(output+slen, "near "); + slen += snprintf(output+slen, outbufsize-slen, "near "); } else if ( (*p)->opd[i] & SHORT ) { - slen += sprintf(output+slen, "short "); + slen += snprintf(output+slen, outbufsize-slen, "short "); } - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) { - slen += sprintf(output+slen, "[%s%s%s0x%lx]", + slen += snprintf(output+slen, outbufsize-slen, "[%s%s%s0x%lx]", (segover ? segover : ""), (segover ? ":" : ""), (ins.oprs[i].addr_size == 32 ? "dword " : @@@@ -669,30 +669,30 @@@@ } else if ( !(REGMEM & ~(*p)->opd[i]) ) { int started = FALSE; if ( (*p)->opd[i] & BITS8 ) - slen += sprintf(output+slen, "byte "); + slen += snprintf(output+slen, outbufsize-slen, "byte "); if ( (*p)->opd[i] & BITS16 ) - slen += sprintf(output+slen, "word "); + slen += snprintf(output+slen, outbufsize-slen, "word "); if ( (*p)->opd[i] & BITS32 ) - slen += sprintf(output+slen, "dword "); + slen += snprintf(output+slen, outbufsize-slen, "dword "); if ( (*p)->opd[i] & BITS64 ) - slen += sprintf(output+slen, "qword "); + slen += snprintf(output+slen, outbufsize-slen, "qword "); if ( (*p)->opd[i] & BITS80 ) - slen += sprintf(output+slen, "tword "); + slen += snprintf(output+slen, outbufsize-slen, "tword "); if ( (*p)->opd[i] & FAR ) - slen += sprintf(output+slen, "far "); + slen += snprintf(output+slen, outbufsize-slen, "far "); if ( (*p)->opd[i] & NEAR ) - slen += sprintf(output+slen, "near "); + slen += snprintf(output+slen, outbufsize-slen, "near "); output[slen++] = '['; if (ins.oprs[i].addr_size) - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", (ins.oprs[i].addr_size == 32 ? "dword " : ins.oprs[i].addr_size == 16 ? "word " : "")); if (segover) { - slen += sprintf(output+slen, "%s:", segover); + slen += snprintf(output+slen, outbufsize-slen, "%s:", segover); segover = NULL; } if (ins.oprs[i].basereg != -1) { - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[(ins.oprs[i].basereg - EXPR_REG_START)]); started = TRUE; @@@@ -700,11 +700,11 @@@@ if (ins.oprs[i].indexreg != -1) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "%s", + slen += snprintf(output+slen, outbufsize-slen, "%s", reg_names[(ins.oprs[i].indexreg - EXPR_REG_START)]); if (ins.oprs[i].scale > 1) - slen += sprintf(output+slen, "*%d", ins.oprs[i].scale); + slen += snprintf(output+slen, outbufsize-slen, "*%d", ins.oprs[i].scale); started = TRUE; } if (ins.oprs[i].segment & SEG_DISP8) { @@@@ -713,20 +713,20 @@@@ ins.oprs[i].offset = - (signed char) ins.oprs[i].offset; sign = '-'; } - slen += sprintf(output+slen, "%c0x%lx", sign, + slen += snprintf(output+slen, outbufsize-slen, "%c0x%lx", sign, ins.oprs[i].offset); } else if (ins.oprs[i].segment & SEG_DISP16) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } else if (ins.oprs[i].segment & SEG_DISP32) { if (started) output[slen++] = '+'; - slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset); + slen += snprintf(output+slen, outbufsize-slen, "0x%lx", ins.oprs[i].offset); } output[slen++] = ']'; } else { - slen += sprintf(output+slen, "", i); + slen += snprintf(output+slen, outbufsize-slen, "", i); } } output[slen] = '\0'; @@@@ -741,8 +741,8 @@@@ return length; } -long eatbyte (unsigned char *data, char *output) +long eatbyte (unsigned char *data, char *output, int outbufsize) { - sprintf(output, "db 0x%02X", *data); + snprintf(output, outbufsize, "db 0x%02X", *data); return 1; } @