diff options
Diffstat (limited to 'output')
-rw-r--r-- | output/codeview.c | 16 | ||||
-rw-r--r-- | output/dwarf.h | 36 | ||||
-rw-r--r-- | output/elf.h | 701 | ||||
-rw-r--r-- | output/macho.h | 282 | ||||
-rw-r--r-- | output/nullout.c | 8 | ||||
-rw-r--r-- | output/outaout.c | 132 | ||||
-rw-r--r-- | output/outas86.c | 69 | ||||
-rw-r--r-- | output/outbin.c | 212 | ||||
-rw-r--r-- | output/outcoff.c | 199 | ||||
-rw-r--r-- | output/outdbg.c | 35 | ||||
-rw-r--r-- | output/outelf.c | 323 | ||||
-rw-r--r-- | output/outelf.h | 1 | ||||
-rw-r--r-- | output/outform.c | 2 | ||||
-rw-r--r-- | output/outieee.c | 94 | ||||
-rw-r--r-- | output/outlib.h | 3 | ||||
-rw-r--r-- | output/outmacho.c | 266 | ||||
-rw-r--r-- | output/outobj.c | 215 | ||||
-rw-r--r-- | output/outrdf2.c | 52 | ||||
-rw-r--r-- | output/pecoff.h | 1 | ||||
-rw-r--r-- | output/stabs.h | 190 | ||||
-rw-r--r-- | output/strtbl.c | 117 | ||||
-rw-r--r-- | output/strtbl.h | 57 |
22 files changed, 1434 insertions, 1577 deletions
diff --git a/output/codeview.c b/output/codeview.c index 15561793..870d573f 100644 --- a/output/codeview.c +++ b/output/codeview.c @@ -38,9 +38,6 @@ #include "version.h" #include "compiler.h" -#include <stdio.h> -#include <stddef.h> -#include <stdlib.h> #include "nasm.h" #include "nasmlib.h" @@ -177,7 +174,6 @@ static void cv8_init(void) cv8_state.source_files = NULL; cv8_state.source_files_tail = &cv8_state.source_files; - hash_init(&cv8_state.file_hash, HASH_MEDIUM); cv8_state.num_files = 0; cv8_state.total_filename_len = 0; @@ -369,9 +365,9 @@ done_0: fclose(f); done: if (!success) { - nasm_error(ERR_NONFATAL, "unable to hash file %s. " - "Debug information may be unavailable.\n", - filename); + nasm_nonfatal("unable to hash file %s. " + "Debug information may be unavailable.", + filename); } return; } @@ -480,7 +476,7 @@ static void register_reloc(struct coff_Section *const sect, return; } } - nasm_panic(0, "codeview: relocation for unregistered symbol: %s", sym); + nasm_panic("codeview: relocation for unregistered symbol: %s", sym); } static inline void section_write32(struct coff_Section *sect, uint32_t val) @@ -655,7 +651,7 @@ static uint16_t write_symbolinfo_properties(struct coff_Section *sect, else if (win32) section_write16(sect, 0x0006); /* machine */ else - nasm_assert(!"neither win32 nor win64 are set!"); + nasm_panic("neither win32 nor win64 are set!"); section_write16(sect, 0); /* verFEMajor */ section_write16(sect, 0); /* verFEMinor */ section_write16(sect, 0); /* verFEBuild */ @@ -712,7 +708,7 @@ static uint16_t write_symbolinfo_symbols(struct coff_Section *sect) section_write8(sect, 0); /* FLAG */ break; default: - nasm_assert(!"unknown symbol type"); + nasm_panic("unknown symbol type"); } section_wbytes(sect, sym->name, strlen(sym->name) + 1); diff --git a/output/dwarf.h b/output/dwarf.h index e672819c..f846b2be 100644 --- a/output/dwarf.h +++ b/output/dwarf.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2018 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -90,6 +90,7 @@ enum dwarf_tag { DW_TAG_variant_part = 0x33, DW_TAG_variable = 0x34, DW_TAG_volatile_type = 0x35, + /* DWARF 3 */ DW_TAG_dwarf_procedure = 0x36, DW_TAG_restrict_type = 0x37, DW_TAG_interface_type = 0x38, @@ -100,6 +101,12 @@ enum dwarf_tag { DW_TAG_imported_unit = 0x3d, DW_TAG_condition = 0x3f, DW_TAG_shared_type = 0x40, + /* DWARF 4 */ + DW_TAG_type_unit = 0x41, + DW_TAG_rvalue_reference_type = 0x42, + DW_TAG_template_alias = 0x43, + /* DWARF 5 */ + DW_TAG_atomic_type = 0x47, DW_TAG_lo_user = 0x4080, DW_TAG_hi_user = 0xffff @@ -131,7 +138,12 @@ enum dwarf_form { DW_FORM_ref4 = 0x13, DW_FORM_ref8 = 0x14, DW_FORM_ref_udata = 0x15, - DW_FORM_indirect = 0x16 + DW_FORM_indirect = 0x16, + /* DWARF 4 */ + DW_FORM_sec_offset = 0x17, + DW_FORM_exprloc = 0x18, + DW_FORM_flag_present = 0x19, + DW_FORM_ref_sig8 = 0x20 }; enum dwarf_attribute { @@ -194,6 +206,7 @@ enum dwarf_attribute { DW_AT_variable_parameter = 0x4b, DW_AT_virtuality = 0x4c, DW_AT_vtable_elem_location = 0x4d, + /* DWARF 3 */ DW_AT_allocated = 0x4e, DW_AT_associated = 0x4f, DW_AT_data_location = 0x50, @@ -221,6 +234,15 @@ enum dwarf_attribute { DW_AT_elemental = 0x66, DW_AT_pure = 0x67, DW_AT_recursive = 0x68, + /* DWARF 4 */ + DW_AT_signature = 0x69, + DW_AT_main_subprogram = 0x6a, + DW_AT_data_bit_offset = 0x6b, + DW_AT_const_expr = 0x6c, + DW_AT_enum_class = 0x6d, + DW_AT_linkage_name = 0x6e, + /* DWARF 5 */ + DW_AT_noreturn = 0x87, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff @@ -372,6 +394,7 @@ enum dwarf_op { DW_OP_deref_size = 0x94, DW_OP_xderef_size = 0x95, DW_OP_nop = 0x96, + /* DWARF 3 */ DW_OP_push_object_address = 0x97, DW_OP_call2 = 0x98, DW_OP_call4 = 0x99, @@ -379,6 +402,9 @@ enum dwarf_op { DW_OP_form_tls_address = 0x9b, DW_OP_call_frame_cfa = 0x9c, DW_OP_bit_piece = 0x9d, + /* DWARF 4 */ + DW_OP_implicit_value = 0x9e, + DW_OP_stack_value = 0x9f, DW_OP_lo_user = 0xe0, DW_OP_hi_user = 0xff @@ -393,6 +419,7 @@ enum dwarf_base_type { DW_ATE_signed_char = 0x06, DW_ATE_unsigned = 0x07, DW_ATE_unsigned_char = 0x08, + /* DWARF 3 */ DW_ATE_imaginary_float = 0x09, DW_ATE_packed_decimal = 0x0a, DW_ATE_numeric_string = 0x0b, @@ -400,6 +427,8 @@ enum dwarf_base_type { DW_ATE_signed_fixed = 0x0d, DW_ATE_unsigned_fixed = 0x0e, DW_ATE_decimal_float = 0x0f, + /* DWARF 4 */ + DW_ATE_UTF = 0x10, DW_ATE_lo_user = 0x80, DW_ATE_hi_user = 0xff @@ -576,7 +605,8 @@ enum dwarf_call_frame { DW_CFA_def_cfa = 0x0c, DW_CFA_def_cfa_register = 0x0d, DW_CFA_def_cfa_offset = 0x0e, - DW_CFA_def_cfa_expression = 0x0f, + /* DWARF 3 */ + DW_CFA_def_cfa_expression = 0x0f, DW_CFA_expression = 0x10, DW_CFA_offset_extended_sf = 0x11, DW_CFA_def_cfa_sf = 0x12, diff --git a/output/elf.h b/output/elf.h index 72b43073..8b83c5c2 100644 --- a/output/elf.h +++ b/output/elf.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2009 The NASM Authors - All Rights Reserved + * Copyright 1996-2018 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -42,110 +42,110 @@ #include "compiler.h" /* Segment types */ -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOOS 0x60000000 -#define PT_HIOS 0x6fffffff -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff -#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ /* ELF file types */ -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 -#define ET_LOPROC 0xff00 -#define ET_HIPROC 0xffff +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff /* ELF machine types */ -#define EM_NONE 0 -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_486 6 /* Not used in Linux at least */ -#define EM_860 7 -#define EM_MIPS 8 /* R3k, bigendian(?) */ -#define EM_MIPS_RS4_BE 10 /* R4k BE */ -#define EM_PARISC 15 -#define EM_SPARC32PLUS 18 -#define EM_PPC 20 -#define EM_PPC64 21 -#define EM_S390 22 -#define EM_SH 42 -#define EM_SPARCV9 43 /* v9 = SPARC64 */ -#define EM_H8_300H 47 -#define EM_H8S 48 -#define EM_IA_64 50 -#define EM_X86_64 62 -#define EM_CRIS 76 -#define EM_V850 87 -#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ -#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ -#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_486 6 /* Not used in Linux at least */ +#define EM_860 7 +#define EM_MIPS 8 /* R3k, bigendian(?) */ +#define EM_MIPS_RS4_BE 10 /* R4k BE */ +#define EM_PARISC 15 +#define EM_SPARC32PLUS 18 +#define EM_PPC 20 +#define EM_PPC64 21 +#define EM_S390 22 +#define EM_SH 42 +#define EM_SPARCV9 43 /* v9 = SPARC64 */ +#define EM_H8_300H 47 +#define EM_H8S 48 +#define EM_IA_64 50 +#define EM_X86_64 62 +#define EM_CRIS 76 +#define EM_V850 87 +#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ +#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ +#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ /* Dynamic type values */ -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff /* Auxilliary table entries */ -#define AT_NULL 0 /* end of vector */ -#define AT_IGNORE 1 /* entry should be ignored */ -#define AT_EXECFD 2 /* file descriptor of program */ -#define AT_PHDR 3 /* program headers for program */ -#define AT_PHENT 4 /* size of program header entry */ -#define AT_PHNUM 5 /* number of program headers */ -#define AT_PAGESZ 6 /* system page size */ -#define AT_BASE 7 /* base address of interpreter */ -#define AT_FLAGS 8 /* flags */ -#define AT_ENTRY 9 /* entry point of program */ -#define AT_NOTELF 10 /* program is not ELF */ -#define AT_UID 11 /* real uid */ -#define AT_EUID 12 /* effective uid */ -#define AT_GID 13 /* real gid */ -#define AT_EGID 14 /* effective gid */ -#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ -#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ -#define AT_CLKTCK 17 /* frequency at which times() increments */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ +#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ +#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_CLKTCK 17 /* frequency at which times() increments */ /* 18..22 = ? */ -#define AT_SECURE 23 /* secure mode boolean */ +#define AT_SECURE 23 /* secure mode boolean */ /* Program header permission flags */ -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 /* Section header types */ #define SHT_NULL 0 @@ -171,16 +171,16 @@ #define SHT_HIUSER 0xffffffff /* Section header flags */ -#define SHF_WRITE (1 << 0) /* Writable */ -#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ -#define SHF_EXECINSTR (1 << 2) /* Executable */ -#define SHF_MERGE (1 << 4) /* Might be merged */ -#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ -#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ -#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ -#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling required */ -#define SHF_GROUP (1 << 9) /* Section is member of a group. */ -#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data */ /* Special section numbers */ #define SHN_UNDEF 0x0000 @@ -203,221 +203,224 @@ #define XSHN_HIRESERVE ((int16_t)SHN_HIRESERVE) /* Section align flag */ -#define SHA_ANY 1 /* No alignment constraint */ +#define SHA_ANY 1 /* No alignment constraint */ /* Lenght of magic at the start of a file */ -#define EI_NIDENT 16 +#define EI_NIDENT 16 /* Magic number constants... */ -#define EI_MAG0 0 /* e_ident[] indexes */ -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_OSABI 7 -#define EI_ABIVERSION 8 -#define EI_NINDENT 16 - -#define ELFMAG0 0x7f /* EI_MAG */ -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define ELFCLASSNONE 0 /* EI_CLASS */ -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define ELFDATANONE 0 /* e_ident[EI_DATA] */ -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define EV_NONE 0 /* e_version, EI_VERSION */ -#define EV_CURRENT 1 -#define EV_NUM 2 - -#define ELFOSABI_NONE 0 -#define ELFOSABI_LINUX 3 - -/* Legal values for ST_BIND subfield of st_info (symbol binding). */ -#define STB_LOCAL 0 /* Local symbol */ -#define STB_GLOBAL 1 /* Global symbol */ -#define STB_WEAK 2 /* Weak symbol */ -#define STB_NUM 3 /* Number of defined types. */ -#define STB_LOOS 10 /* Start of OS-specific */ -#define STB_HIOS 12 /* End of OS-specific */ -#define STB_LOPROC 13 /* Start of processor-specific */ -#define STB_HIPROC 15 /* End of processor-specific */ +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_ABIVERSION 8 +#define EI_NINDENT 16 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +#define ELFOSABI_NONE 0 +#define ELFOSABI_LINUX 3 + +/* Legal values for ST_BIND subfield of st_info (symbol binding) */ +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ /* Symbol types */ -#define STT_NOTYPE 0 /* Symbol type is unspecified */ -#define STT_OBJECT 1 /* Symbol is a data object */ -#define STT_FUNC 2 /* Symbol is a code object */ -#define STT_SECTION 3 /* Symbol associated with a section */ -#define STT_FILE 4 /* Symbol's name is file name */ -#define STT_COMMON 5 /* Symbol is a common data object */ -#define STT_TLS 6 /* Symbol is thread-local data object*/ -#define STT_NUM 7 /* Number of defined types. */ +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object */ +#define STT_NUM 7 /* Number of defined types */ /* Symbol visibilities */ -#define STV_DEFAULT 0 /* Default symbol visibility rules */ -#define STV_INTERNAL 1 /* Processor specific hidden class */ -#define STV_HIDDEN 2 /* Sym unavailable in other modules */ -#define STV_PROTECTED 3 /* Not preemptible, not exported */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ /* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field */ -#define ELF32_ST_BIND(i) ((i) >> 4) -#define ELF32_ST_MKBIND(i) ((i) << 4) /* just a helper */ -#define ELF32_ST_TYPE(i) ((i) & 0xf) -#define ELF32_ST_INFO(b, i) (ELF32_ST_MKBIND(b) + ELF32_ST_TYPE(i)) +#define ELF32_ST_BIND(i) ((i) >> 4) +#define ELF32_ST_MKBIND(i) ((i) << 4) /* just a helper */ +#define ELF32_ST_TYPE(i) ((i) & 0xf) +#define ELF32_ST_INFO(b, i) (ELF32_ST_MKBIND(b) + ELF32_ST_TYPE(i)) -#define ELF64_ST_BIND(i) ELF32_ST_BIND(i) -#define ELF64_ST_MKBIND(i) ELF32_ST_MKBIND(i) -#define ELF64_ST_TYPE(i) ELF32_ST_TYPE(i) -#define ELF64_ST_INFO(b, i) ELF32_ST_INFO(b, i) +#define ELF64_ST_BIND(i) ELF32_ST_BIND(i) +#define ELF64_ST_MKBIND(i) ELF32_ST_MKBIND(i) +#define ELF64_ST_TYPE(i) ELF32_ST_TYPE(i) +#define ELF64_ST_INFO(b, i) ELF32_ST_INFO(b, i) /* * ELF standard typedefs (yet more proof that <stdint.h> was way overdue) */ -typedef uint16_t Elf32_Half; -typedef int16_t Elf32_SHalf; -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; +typedef uint16_t Elf32_Half; +typedef int16_t Elf32_SHalf; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; -typedef uint32_t Elf32_Off; -typedef uint32_t Elf32_Addr; -typedef uint16_t Elf32_Section; +typedef uint32_t Elf32_Off; +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Section; -typedef uint16_t Elf64_Half; -typedef int16_t Elf64_SHalf; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; +typedef uint16_t Elf64_Half; +typedef int16_t Elf64_SHalf; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; -typedef uint64_t Elf64_Off; -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Section; +typedef uint64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint16_t Elf64_Section; /* * Dynamic header */ typedef struct elf32_dyn { - Elf32_Sword d_tag; - union { - Elf32_Sword d_val; - Elf32_Addr d_ptr; - } d_un; + Elf32_Sword d_tag; + union { + Elf32_Sword d_val; + Elf32_Addr d_ptr; + } d_un; } Elf32_Dyn; typedef struct elf64_dyn { - Elf64_Sxword d_tag; - union { - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; + Elf64_Sxword d_tag; + union { + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; } Elf64_Dyn; /* * Relocations */ -#define ELF32_R_SYM(x) ((x) >> 8) -#define ELF32_R_TYPE(x) ((x) & 0xff) -#define ELF32_R_INFO(s,t) (((Elf32_Word)(s) << 8) + ELF32_R_TYPE(t)) +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xff) +#define ELF32_R_INFO(s,t) (((Elf32_Word)(s) << 8) + ELF32_R_TYPE(t)) typedef struct elf32_rel { - Elf32_Addr r_offset; - Elf32_Word r_info; + Elf32_Addr r_offset; + Elf32_Word r_info; } Elf32_Rel; typedef struct elf32_rela { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; } Elf32_Rela; enum reloc32_type { - R_386_32 = 1, /* ordinary absolute relocation */ - R_386_PC32 = 2, /* PC-relative relocation */ - R_386_GOT32 = 3, /* an offset into GOT */ - R_386_PLT32 = 4, /* a PC-relative offset into PLT */ - R_386_COPY = 5, /* ??? */ - R_386_GLOB_DAT = 6, /* ??? */ - R_386_JUMP_SLOT = 7, /* ??? */ - R_386_RELATIVE = 8, /* ??? */ - R_386_GOTOFF = 9, /* an offset from GOT base */ - R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */ - R_386_TLS_TPOFF = 14, /* Offset in static TLS block */ - R_386_TLS_IE = 15, /* Address of GOT entry for static TLS block offset */ - /* These are GNU extensions, but useful */ - R_386_16 = 20, /* A 16-bit absolute relocation */ - R_386_PC16 = 21, /* A 16-bit PC-relative relocation */ - R_386_8 = 22, /* An 8-bit absolute relocation */ - R_386_PC8 = 23 /* An 8-bit PC-relative relocation */ + R_386_32 = 1, /* ordinary absolute relocation */ + R_386_PC32 = 2, /* PC-relative relocation */ + R_386_GOT32 = 3, /* an offset into GOT */ + R_386_PLT32 = 4, /* a PC-relative offset into PLT */ + R_386_COPY = 5, /* ??? */ + R_386_GLOB_DAT = 6, /* ??? */ + R_386_JUMP_SLOT = 7, /* ??? */ + R_386_RELATIVE = 8, /* ??? */ + R_386_GOTOFF = 9, /* an offset from GOT base */ + R_386_GOTPC = 10, /* a PC-relative offset _to_ GOT */ + R_386_TLS_TPOFF = 14, /* Offset in static TLS block */ + R_386_TLS_IE = 15, /* Address of GOT entry for static TLS block offset */ + /* These are GNU extensions, but useful */ + R_386_16 = 20, /* A 16-bit absolute relocation */ + R_386_PC16 = 21, /* A 16-bit PC-relative relocation */ + R_386_8 = 22, /* An 8-bit absolute relocation */ + R_386_PC8 = 23, /* An 8-bit PC-relative relocation */ + R_386_SEG16 = 45, /* A 16-bit real-mode segment */ + R_386_SUB16 = 46, /* Subtract 16-bit value */ + R_386_SUB32 = 47 /* Subtract 32-bit value */ }; -#define ELF64_R_SYM(x) ((x) >> 32) -#define ELF64_R_TYPE(x) ((x) & 0xffffffff) -#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s) << 32) + ELF64_R_TYPE(t)) +#define ELF64_R_SYM(x) ((x) >> 32) +#define ELF64_R_TYPE(x) ((x) & 0xffffffff) +#define ELF64_R_INFO(s,t) (((Elf64_Xword)(s) << 32) + ELF64_R_TYPE(t)) typedef struct elf64_rel { - Elf64_Addr r_offset; - Elf64_Xword r_info; + Elf64_Addr r_offset; + Elf64_Xword r_info; } Elf64_Rel; typedef struct elf64_rela { - Elf64_Addr r_offset; - Elf64_Xword r_info; - Elf64_Sxword r_addend; + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; } Elf64_Rela; enum reloc64_type { - R_X86_64_NONE = 0, /* No reloc */ - R_X86_64_64 = 1, /* Direct 64 bit */ - R_X86_64_PC32 = 2, /* PC relative 32 bit signed */ - R_X86_64_GOT32 = 3, /* 32 bit GOT entry */ - R_X86_64_PLT32 = 4, /* 32 bit PLT address */ - R_X86_64_COPY = 5, /* Copy symbol at runtime */ - R_X86_64_GLOB_DAT = 6, /* Create GOT entry */ - R_X86_64_JUMP_SLOT = 7, /* Create PLT entry */ - R_X86_64_RELATIVE = 8, /* Adjust by program base */ - R_X86_64_GOTPCREL = 9, /* 32 bit signed PC relative offset to GOT */ - R_X86_64_32 = 10, /* Direct 32 bit zero extended */ - R_X86_64_32S = 11, /* Direct 32 bit sign extended */ - R_X86_64_16 = 12, /* Direct 16 bit zero extended */ - R_X86_64_PC16 = 13, /* 16 bit sign extended pc relative */ - R_X86_64_8 = 14, /* Direct 8 bit sign extended */ - R_X86_64_PC8 = 15, /* 8 bit sign extended pc relative */ - R_X86_64_DTPMOD64 = 16, /* ID of module containing symbol */ - R_X86_64_DTPOFF64 = 17, /* Offset in module's TLS block */ - R_X86_64_TPOFF64 = 18, /* Offset in initial TLS block */ - R_X86_64_TLSGD = 19, /* 32 bit signed PC relative offset to two GOT entries for GD symbol */ - R_X86_64_TLSLD = 20, /* 32 bit signed PC relative offset to two GOT entries for LD symbol */ - R_X86_64_DTPOFF32 = 21, /* Offset in TLS block */ - R_X86_64_GOTTPOFF = 22, /* 32 bit signed PC relative offset to GOT entry for IE symbol */ - R_X86_64_TPOFF32 = 23, /* Offset in initial TLS block */ - R_X86_64_PC64 = 24, /* word64 S + A - P */ - R_X86_64_GOTOFF64 = 25, /* word64 S + A - GOT */ - R_X86_64_GOTPC32 = 26, /* word32 GOT + A - P */ - R_X86_64_GOT64 = 27, /* word64 G + A */ - R_X86_64_GOTPCREL64 = 28, /* word64 G + GOT - P + A */ - R_X86_64_GOTPC64 = 29, /* word64 GOT - P + A */ - R_X86_64_GOTPLT64 = 30, /* word64 G + A */ - R_X86_64_PLTOFF64 = 31, /* word64 L - GOT + A */ - R_X86_64_SIZE32 = 32, /* word32 Z + A */ - R_X86_64_SIZE64 = 33, /* word64 Z + A */ - R_X86_64_GOTPC32_TLSDESC = 34, /* word32 */ - R_X86_64_TLSDESC_CALL = 35, /* none */ - R_X86_64_TLSDESC = 36 /* word64?2 */ + R_X86_64_NONE = 0, /* No reloc */ + R_X86_64_64 = 1, /* Direct 64 bit */ + R_X86_64_PC32 = 2, /* PC relative 32 bit signed */ + R_X86_64_GOT32 = 3, /* 32 bit GOT entry */ + R_X86_64_PLT32 = 4, /* 32 bit PLT address */ + R_X86_64_COPY = 5, /* Copy symbol at runtime */ + R_X86_64_GLOB_DAT = 6, /* Create GOT entry */ + R_X86_64_JUMP_SLOT = 7, /* Create PLT entry */ + R_X86_64_RELATIVE = 8, /* Adjust by program base */ + R_X86_64_GOTPCREL = 9, /* 32 bit signed PC relative offset to GOT */ + R_X86_64_32 = 10, /* Direct 32 bit zero extended */ + R_X86_64_32S = 11, /* Direct 32 bit sign extended */ + R_X86_64_16 = 12, /* Direct 16 bit zero extended */ + R_X86_64_PC16 = 13, /* 16 bit sign extended pc relative */ + R_X86_64_8 = 14, /* Direct 8 bit sign extended */ + R_X86_64_PC8 = 15, /* 8 bit sign extended pc relative */ + R_X86_64_DTPMOD64 = 16, /* ID of module containing symbol */ + R_X86_64_DTPOFF64 = 17, /* Offset in module's TLS block */ + R_X86_64_TPOFF64 = 18, /* Offset in initial TLS block */ + R_X86_64_TLSGD = 19, /* 32 bit signed PC relative offset to two GOT entries for GD symbol */ + R_X86_64_TLSLD = 20, /* 32 bit signed PC relative offset to two GOT entries for LD symbol */ + R_X86_64_DTPOFF32 = 21, /* Offset in TLS block */ + R_X86_64_GOTTPOFF = 22, /* 32 bit signed PC relative offset to GOT entry for IE symbol */ + R_X86_64_TPOFF32 = 23, /* Offset in initial TLS block */ + R_X86_64_PC64 = 24, /* word64 S + A - P */ + R_X86_64_GOTOFF64 = 25, /* word64 S + A - GOT */ + R_X86_64_GOTPC32 = 26, /* word32 GOT + A - P */ + R_X86_64_GOT64 = 27, /* word64 G + A */ + R_X86_64_GOTPCREL64 = 28, /* word64 G + GOT - P + A */ + R_X86_64_GOTPC64 = 29, /* word64 GOT - P + A */ + R_X86_64_GOTPLT64 = 30, /* word64 G + A */ + R_X86_64_PLTOFF64 = 31, /* word64 L - GOT + A */ + R_X86_64_SIZE32 = 32, /* word32 Z + A */ + R_X86_64_SIZE64 = 33, /* word64 Z + A */ + R_X86_64_GOTPC32_TLSDESC= 34, /* word32 */ + R_X86_64_TLSDESC_CALL = 35, /* none */ + R_X86_64_TLSDESC = 36 /* word64?2 */ }; /* @@ -425,21 +428,21 @@ enum reloc64_type { */ typedef struct elf32_sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; } Elf32_Sym; typedef struct elf64_sym { - Elf64_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf64_Half st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; + Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; } Elf64_Sym; /* @@ -447,37 +450,37 @@ typedef struct elf64_sym { */ typedef struct elf32_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; } Elf32_Ehdr; typedef struct elf64_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; } Elf64_Ehdr; /* @@ -485,25 +488,25 @@ typedef struct elf64_hdr { */ typedef struct elf32_phdr { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; } Elf32_Phdr; typedef struct elf64_phdr { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; - Elf64_Xword p_memsz; - Elf64_Xword p_align; + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; } Elf64_Phdr; /* @@ -511,44 +514,44 @@ typedef struct elf64_phdr { */ typedef struct elf32_shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; } Elf32_Shdr; typedef struct elf64_shdr { - Elf64_Word sh_name; - Elf64_Word sh_type; - Elf64_Xword sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf64_Xword sh_size; - Elf64_Word sh_link; - Elf64_Word sh_info; - Elf64_Xword sh_addralign; - Elf64_Xword sh_entsize; + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; } Elf64_Shdr; /* * Note header */ typedef struct elf32_note { - Elf32_Word n_namesz; /* Name size */ - Elf32_Word n_descsz; /* Content size */ - Elf32_Word n_type; /* Content type */ + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ } Elf32_Nhdr; typedef struct elf64_note { - Elf64_Word n_namesz; /* Name size */ - Elf64_Word n_descsz; /* Content size */ - Elf64_Word n_type; /* Content type */ + Elf64_Word n_namesz; /* Name size */ + Elf64_Word n_descsz; /* Content size */ + Elf64_Word n_type; /* Content type */ } Elf64_Nhdr; #endif /* OUTPUT_ELF_H */ diff --git a/output/macho.h b/output/macho.h new file mode 100644 index 00000000..538c531e --- /dev/null +++ b/output/macho.h @@ -0,0 +1,282 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 1996-2018 The NASM Authors - All Rights Reserved + * See the file AUTHORS included with the NASM distribution for + * the specific copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following + * conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * 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 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ----------------------------------------------------------------------- */ + +#ifndef OUTPUT_MACHO_H +#define OUTPUT_MACHO_H + +#include "compiler.h" + +/* Magics */ +#define MH_MAGIC 0xfeedface +#define MH_MAGIC_64 0xfeedfacf + +/* File types */ +#define MH_OBJECT 0x1 + +/* CPUs */ +#define CPU_ARCH_MASK 0xff000000 +#define CPU_ARCH_ABI64 0x01000000 +#define CPU_TYPE_X86 7 +#define CPU_TYPE_I386 CPU_TYPE_X86 +#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) + +#define CPU_SUBTYPE_MASK 0xff000000 +#define CPU_SUBTYPE_I386_ALL 3 + +/* Header flags */ +#define MH_SUBSECTIONS_VIA_SYMBOLS 0x00002000 + +/* Load commands */ +#define LC_SEGMENT 0x1 +#define LC_SEGMENT_64 0x19 +#define LC_SYMTAB 0x2 + +/* Symbol type bits */ +#define N_STAB 0xe0 +#define N_PEXT 0x10 +#define N_TYPE 0x0e +#define N_EXT 0x01 + +/* To mask with N_TYPE */ +#define N_UNDF 0x00 +#define N_ABS 0x02 +#define N_INDR 0x0a +#define N_PBUD 0x0c +#define N_SECT 0x0e + +/* Section ordinals */ +#define NO_SECT 0x00 +#define MAX_SECT 0xff + +/* Section bits */ +#define SECTION_TYPE 0x000000ff +#define SECTION_ATTRIBUTES 0xffffff00 +#define SECTION_ATTRIBUTES_USR 0xff000000 +#define SECTION_ATTRIBUTES_SYS 0x00ffff00 + +#define S_REGULAR 0x00 +#define S_ZEROFILL 0x01 +#define S_CSTRING_LITERALS 0x02 +#define S_4BYTE_LITERALS 0x03 +#define S_8BYTE_LITERALS 0x04 +#define S_LITERAL_POINTERS 0x05 +#define S_NON_LAZY_SYMBOL_POINTERS 0x06 +#define S_LAZY_SYMBOL_POINTERS 0x07 +#define S_SYMBOL_STUBS 0x08 +#define S_MOD_INIT_FUNC_POINTERS 0x09 +#define S_MOD_TERM_FUNC_POINTERS 0x0a +#define S_COALESCED 0x0b +#define S_GB_ZEROFILL 0x0c +#define S_INTERPOSING 0x0d +#define S_16BYTE_LITERALS 0x0e +#define S_DTRACE_DOF 0x0f +#define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 +#define S_THREAD_LOCAL_REGULAR 0x11 +#define S_THREAD_LOCAL_ZEROFILL 0x12 +#define S_THREAD_LOCAL_VARIABLES 0x13 +#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 +#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 + +#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 +#define S_ATTR_NO_TOC 0x40000000 +#define S_ATTR_STRIP_STATIC_SYMS 0x20000000 +#define S_ATTR_NO_DEAD_STRIP 0x10000000 +#define S_ATTR_LIVE_SUPPORT 0x08000000 +#define S_ATTR_SELF_MODIFYING_CODE 0x04000000 +#define S_ATTR_DEBUG 0x02000000 + +#define S_ATTR_SOME_INSTRUCTIONS 0x00000400 +#define S_ATTR_EXT_RELOC 0x00000200 +#define S_ATTR_LOC_RELOC 0x00000100 +#define INDIRECT_SYMBOL_LOCAL 0x80000000 +#define INDIRECT_SYMBOL_ABS 0x40000000 + +/* Relocation info type */ +#define GENERIC_RELOC_VANILLA 0 +#define GENERIC_RELOC_PAIR 1 +#define GENERIC_RELOC_SECTDIFF 2 +#define GENERIC_RELOC_PB_LA_PTR 3 +#define GENERIC_RELOC_LOCAL_SECTDIFF 4 +#define GENERIC_RELOC_TLV 5 + +#define X86_64_RELOC_UNSIGNED 0 +#define X86_64_RELOC_SIGNED 1 +#define X86_64_RELOC_BRANCH 2 +#define X86_64_RELOC_GOT_LOAD 3 +#define X86_64_RELOC_GOT 4 +#define X86_64_RELOC_SUBTRACTOR 5 +#define X86_64_RELOC_SIGNED_1 6 +#define X86_64_RELOC_SIGNED_2 7 +#define X86_64_RELOC_SIGNED_4 8 +#define X86_64_RELOC_TLV 9 + +/* Relocation info */ +#define R_ABS 0 +#define R_SCATTERED 0x80000000 + +/* VM permission constants */ +#define VM_PROT_NONE 0x00 +#define VM_PROT_READ 0x01 +#define VM_PROT_WRITE 0x02 +#define VM_PROT_EXECUTE 0x04 + +typedef struct { + uint32_t magic; + uint32_t cputype; + uint32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; +} macho_header_t; + +typedef struct { + uint32_t magic; + uint32_t cputype; + uint32_t cpusubtype; + uint32_t filetype; + uint32_t ncmds; + uint32_t sizeofcmds; + uint32_t flags; + uint32_t reserved; +} macho_header_64_t; + +typedef struct { + uint32_t cmd; + uint32_t cmdsize; +} macho_load_command_t; + +typedef struct { + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint32_t vmaddr; + uint32_t vmsize; + uint32_t fileoff; + uint32_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} macho_segment_command_t; + +typedef struct { + uint32_t cmd; + uint32_t cmdsize; + char segname[16]; + uint64_t vmaddr; + uint64_t vmsize; + uint64_t fileoff; + uint64_t filesize; + uint32_t maxprot; + uint32_t initprot; + uint32_t nsects; + uint32_t flags; +} macho_segment_command_64_t; + +typedef struct { + char sectname[16]; + char segname[16]; + uint32_t addr; + uint32_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; +} macho_section_t; + +typedef struct { + char sectname[16]; + char segname[16]; + uint64_t addr; + uint64_t size; + uint32_t offset; + uint32_t align; + uint32_t reloff; + uint32_t nreloc; + uint32_t flags; + uint32_t reserved1; + uint32_t reserved2; + uint32_t reserved3; +} macho_section_64_t; + +typedef struct { + uint32_t cmd; + uint32_t cmdsize; + uint32_t symoff; + uint32_t nsyms; + uint32_t stroff; + uint32_t strsize; +} macho_symtab_command_t; + +typedef struct { + int32_t r_address; + union { + struct { + uint32_t r_symbolnum: 24, + r_pcrel: 1, + r_length: 2, + r_extern: 1, + r_type: 4; + } s; + uint32_t r_raw; + } u; +} macho_relocation_info_t; + +typedef struct nlist_base { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; +} macho_nlist_base_t; + +typedef struct nlist { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + int16_t n_desc; + uint32_t n_value; +} macho_nlist_t; + +typedef struct { + uint32_t n_strx; + uint8_t n_type; + uint8_t n_sect; + uint16_t n_desc; + uint64_t n_value; +} macho_nlist_64_t; + +#endif /* OUTPUT_MACHO_H */ diff --git a/output/nullout.c b/output/nullout.c index daf24f53..121fe70b 100644 --- a/output/nullout.c +++ b/output/nullout.c @@ -36,11 +36,10 @@ #include "outlib.h" enum directive_result -null_directive(enum directive directive, char *value, int pass) +null_directive(enum directive directive, char *value) { (void)directive; (void)value; - (void)pass; return DIRR_UNKNOWN; } @@ -54,3 +53,8 @@ void null_reset(void) { /* Nothing to do */ } + +int32_t null_segbase(int32_t segment) +{ + return segment; +} diff --git a/output/outaout.c b/output/outaout.c index ba2dbd5e..8821d7fe 100644 --- a/output/outaout.c +++ b/output/outaout.c @@ -38,10 +38,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -236,11 +233,8 @@ static void aout_cleanup(void) saa_free(strs); } -static int32_t aout_section_names(char *name, int pass, int *bits) +static int32_t aout_section_names(char *name, int *bits) { - - (void)pass; - /* * Default to 32 bits. */ @@ -275,7 +269,7 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") && strcmp(name, "..got") && strcmp(name, "..plt") && strcmp(name, "..sym")) - nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_nonfatal("unrecognised special symbol `%s'", name); return; } @@ -298,8 +292,8 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL); if (e) { if (!is_simple(e)) - nasm_error(ERR_NONFATAL, "cannot use relocatable" - " expression as symbol size"); + nasm_nonfatal("cannot use relocatable" + " expression as symbol size"); else (*s)->size = reloc_value(e); } @@ -367,8 +361,8 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, !nasm_strnicmp(special, "object", n)) sym->type |= SYM_DATA; else - nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'", - n, special); + nasm_nonfatal("unrecognised symbol type `%.*s'", + n, special); if (special[n]) { struct tokenval tokval; expr *e; @@ -376,8 +370,8 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, char *saveme = stdscan_get(); if (!bsd) { - nasm_error(ERR_NONFATAL, "Linux a.out does not support" - " symbol size information"); + nasm_nonfatal("Linux a.out does not support" + " symbol size information"); } else { while (special[n] && nasm_isspace(special[n])) n++; @@ -396,8 +390,8 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, sym->name = nasm_strdup(name); } else if (e) { if (!is_simple(e)) - nasm_error(ERR_NONFATAL, "cannot use relocatable" - " expression as symbol size"); + nasm_nonfatal("cannot use relocatable" + " expression as symbol size"); else sym->size = reloc_value(e); } @@ -422,7 +416,7 @@ static void aout_deflabel(char *name, int32_t segment, int64_t offset, nsyms++; /* and another for the size */ if (special && !special_used) - nasm_error(ERR_NONFATAL, "no special symbol features supported here"); + nasm_nonfatal("no special symbol features supported here"); } static void aout_add_reloc(struct Section *sect, int32_t segment, @@ -490,8 +484,8 @@ static int32_t aout_add_gsym_reloc(struct Section *sect, shead = sbss.gsyms; if (!shead) { if (exact && offset != 0) - nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol" - " for this reference"); + nasm_nonfatal("unable to find a suitable global symbol" + " for this reference"); else aout_add_reloc(sect, segment, type, bytes); return offset; @@ -514,8 +508,8 @@ static int32_t aout_add_gsym_reloc(struct Section *sect, sym = sm; } if (!sym && exact) { - nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol" - " for this reference"); + nasm_nonfatal("unable to find a suitable global symbol" + " for this reference"); return 0; } @@ -561,8 +555,8 @@ static int32_t aout_add_gotoff_reloc(struct Section *sect, int32_t segment, else if (segment == sbss.index) asym = sbss.asym; if (!asym) - nasm_error(ERR_NONFATAL, "`..gotoff' relocations require a non-global" - " symbol in the section"); + nasm_nonfatal("`..gotoff' relocations require a non-global" + " symbol in the section"); r = *sect->tail = nasm_malloc(sizeof(struct Reloc)); sect->tail = &r->next; @@ -586,16 +580,6 @@ static void aout_out(int32_t segto, const void *data, int32_t addr; uint8_t mydata[4], *p; - /* - * handle absolute-assembly (structure definitions) - */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); - return; - } - if (segto == stext.index) s = &stext; else if (segto == sdata.index) @@ -603,14 +587,14 @@ static void aout_out(int32_t segto, const void *data, else if (segto == sbss.index) s = NULL; else { - nasm_error(ERR_WARNING, "attempt to assemble code in" - " segment %d: defaulting to `.text'", segto); + nasm_warn(WARN_OTHER, "attempt to assemble code in" + " segment %d: defaulting to `.text'", segto); s = &stext; } if (!s && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in the" - " BSS section: ignored"); + nasm_warn(WARN_OTHER, "attempt to initialize memory in the" + " BSS section: ignored"); sbss.len += realsize(type, size); return; } @@ -619,30 +603,27 @@ static void aout_out(int32_t segto, const void *data, if (type == OUT_RESERVE) { if (s) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " %s section: zeroing", - (segto == stext.index ? "code" : "data")); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " %s section: zeroing", + (segto == stext.index ? "code" : "data")); aout_sect_write(s, NULL, size); } else sbss.len += size; } else if (type == OUT_RAWDATA) { - if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); aout_sect_write(s, data, size); } else if (type == OUT_ADDRESS) { int asize = abs((int)size); addr = *(int64_t *)data; if (segment != NO_SEG) { if (segment % 2) { - nasm_error(ERR_NONFATAL, "a.out format does not support" - " segment base references"); + nasm_nonfatal("a.out format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { aout_add_reloc(s, segment, RELTYPE_ABSOLUTE, asize); } else if (!bsd) { - nasm_error(ERR_NONFATAL, - "Linux a.out format does not support" - " any use of WRT"); + nasm_nonfatal("Linux a.out format does not support" + " any use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } else if (wrt == aout_gotpc_sect + 1) { is_pic = 0x40; @@ -660,13 +641,11 @@ static void aout_out(int32_t segto, const void *data, false); } else if (wrt == aout_plt_sect + 1) { is_pic = 0x40; - nasm_error(ERR_NONFATAL, - "a.out format cannot produce non-PC-" - "relative PLT references"); + nasm_nonfatal("a.out format cannot produce non-PC-" + "relative PLT references"); } else { - nasm_error(ERR_NONFATAL, - "a.out format does not support this" - " use of WRT"); + nasm_nonfatal("a.out format does not support this" + " use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } } @@ -678,17 +657,15 @@ static void aout_out(int32_t segto, const void *data, WRITELONG(p, addr); aout_sect_write(s, mydata, asize); } else if (type == OUT_REL2ADR) { - if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL2ADR"); if (segment != NO_SEG && segment % 2) { - nasm_error(ERR_NONFATAL, "a.out format does not support" - " segment base references"); + nasm_nonfatal("a.out format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { aout_add_reloc(s, segment, RELTYPE_RELATIVE, 2); } else if (!bsd) { - nasm_error(ERR_NONFATAL, "Linux a.out format does not support" - " any use of WRT"); + nasm_nonfatal("Linux a.out format does not support" + " any use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } else if (wrt == aout_plt_sect + 1) { is_pic = 0x40; @@ -696,11 +673,11 @@ static void aout_out(int32_t segto, const void *data, } else if (wrt == aout_gotpc_sect + 1 || wrt == aout_gotoff_sect + 1 || wrt == aout_got_sect + 1) { - nasm_error(ERR_NONFATAL, "a.out format cannot produce PC-" - "relative GOT references"); + nasm_nonfatal("a.out format cannot produce PC-" + "relative GOT references"); } else { - nasm_error(ERR_NONFATAL, "a.out format does not support this" - " use of WRT"); + nasm_nonfatal("a.out format does not support this" + " use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } } @@ -708,17 +685,15 @@ static void aout_out(int32_t segto, const void *data, WRITESHORT(p, *(int64_t *)data - (size + s->len)); aout_sect_write(s, mydata, 2L); } else if (type == OUT_REL4ADR) { - if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL4ADR"); if (segment != NO_SEG && segment % 2) { - nasm_error(ERR_NONFATAL, "a.out format does not support" - " segment base references"); + nasm_nonfatal("a.out format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { aout_add_reloc(s, segment, RELTYPE_RELATIVE, 4); } else if (!bsd) { - nasm_error(ERR_NONFATAL, "Linux a.out format does not support" - " any use of WRT"); + nasm_nonfatal("Linux a.out format does not support" + " any use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } else if (wrt == aout_plt_sect + 1) { is_pic = 0x40; @@ -726,11 +701,11 @@ static void aout_out(int32_t segto, const void *data, } else if (wrt == aout_gotpc_sect + 1 || wrt == aout_gotoff_sect + 1 || wrt == aout_got_sect + 1) { - nasm_error(ERR_NONFATAL, "a.out format cannot produce PC-" - "relative GOT references"); + nasm_nonfatal("a.out format cannot produce PC-" + "relative GOT references"); } else { - nasm_error(ERR_NONFATAL, "a.out format does not support this" - " use of WRT"); + nasm_nonfatal("a.out format does not support this" + " use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } } @@ -889,11 +864,6 @@ static void aout_sect_write(struct Section *sect, sect->len += len; } -static int32_t aout_segbase(int32_t segment) -{ - return segment; -} - extern macros_t aout_stdmac[]; #endif /* OF_AOUT || OF_AOUTB */ @@ -917,7 +887,7 @@ const struct ofmt of_aout = { aout_section_names, NULL, null_sectalign, - aout_segbase, + null_segbase, null_directive, aout_cleanup, NULL /* pragma list */ @@ -944,7 +914,7 @@ const struct ofmt of_aoutb = { aout_section_names, NULL, null_sectalign, - aout_segbase, + null_segbase, null_directive, aout_cleanup, NULL /* pragma list */ diff --git a/output/outas86.c b/output/outas86.c index 3f9867b9..3b44aea9 100644 --- a/output/outas86.c +++ b/output/outas86.c @@ -38,10 +38,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -159,11 +156,8 @@ static void as86_cleanup(void) saa_free(strs); } -static int32_t as86_section_names(char *name, int pass, int *bits) +static int32_t as86_section_names(char *name, int *bits) { - - (void)pass; - /* * Default is 16 bits. */ @@ -200,13 +194,13 @@ static void as86_deflabel(char *name, int32_t segment, int64_t offset, struct Symbol *sym; if (special) - nasm_error(ERR_NONFATAL, "as86 format does not support any" - " special symbol types"); + nasm_nonfatal("as86 format does not support any" + " special symbol types"); if (name[0] == '.' && name[1] == '.' && name[2] != '@') { if (strcmp(name, "..start")) { - nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_nonfatal("unrecognised special symbol `%s'", name); return; } else { is_start = true; @@ -294,17 +288,7 @@ static void as86_out(int32_t segto, const void *data, if (wrt != NO_SEG) { wrt = NO_SEG; /* continue to do _something_ */ - nasm_error(ERR_NONFATAL, "WRT not supported by as86 output format"); - } - - /* - * handle absolute-assembly (structure definitions) - */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); - return; + nasm_nonfatal("WRT not supported by as86 output format"); } if (segto == stext.index) @@ -314,14 +298,14 @@ static void as86_out(int32_t segto, const void *data, else if (segto == bssindex) s = NULL; else { - nasm_error(ERR_WARNING, "attempt to assemble code in" - " segment %d: defaulting to `.text'", segto); + nasm_warn(WARN_OTHER, "attempt to assemble code in" + " segment %d: defaulting to `.text'", segto); s = &stext; } if (!s && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in the" - " BSS section: ignored"); + nasm_warn(WARN_OTHER, "attempt to initialize memory in the" + " BSS section: ignored"); bsslen += realsize(type, size); return; } @@ -330,24 +314,22 @@ static void as86_out(int32_t segto, const void *data, if (type == OUT_RESERVE) { if (s) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " %s section: zeroing", - (segto == stext.index ? "code" : "data")); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " %s section: zeroing", + (segto == stext.index ? "code" : "data")); as86_sect_write(s, NULL, size); as86_add_piece(s, 0, 0L, 0L, size, 0); } else bsslen += size; } else if (type == OUT_RAWDATA) { - if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); as86_sect_write(s, data, size); as86_add_piece(s, 0, 0L, 0L, size, 0); } else if (type == OUT_ADDRESS) { int asize = abs((int)size); if (segment != NO_SEG) { if (segment % 2) { - nasm_error(ERR_NONFATAL, "as86 format does not support" - " segment base references"); + nasm_nonfatal("as86 format does not support" + " segment base references"); } else { offset = *(int64_t *)data; as86_add_piece(s, 1, offset, segment, asize, 0); @@ -359,12 +341,10 @@ static void as86_out(int32_t segto, const void *data, as86_add_piece(s, 0, 0L, 0L, asize, 0); } } else if (type == OUT_REL2ADR) { - if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL2ADR"); if (segment != NO_SEG) { if (segment % 2) { - nasm_error(ERR_NONFATAL, "as86 format does not support" - " segment base references"); + nasm_nonfatal("as86 format does not support" + " segment base references"); } else { offset = *(int64_t *)data; as86_add_piece(s, 1, offset - size + 2, segment, 2L, @@ -372,12 +352,10 @@ static void as86_out(int32_t segto, const void *data, } } } else if (type == OUT_REL4ADR) { - if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL4ADR"); if (segment != NO_SEG) { if (segment % 2) { - nasm_error(ERR_NONFATAL, "as86 format does not support" - " segment base references"); + nasm_nonfatal("as86 format does not support" + " segment base references"); } else { offset = *(int64_t *)data; as86_add_piece(s, 1, offset - size + 4, segment, 4L, @@ -514,7 +492,7 @@ static void as86_set_rsize(int size) fputc(0x03, ofile); break; default: - nasm_panic(0, "bizarre relocation size %d", size); + nasm_panic("bizarre relocation size %d", size); break; } } @@ -605,11 +583,6 @@ static void as86_sect_write(struct Section *sect, sect->datalen += len; } -static int32_t as86_segbase(int32_t segment) -{ - return segment; -} - extern macros_t as86_stdmac[]; const struct ofmt of_as86 = { @@ -629,7 +602,7 @@ const struct ofmt of_as86 = { as86_section_names, NULL, null_sectalign, - as86_segbase, + null_segbase, null_directive, as86_cleanup, NULL /* pragma list */ diff --git a/output/outbin.c b/output/outbin.c index 28535f99..9983cd33 100644 --- a/output/outbin.c +++ b/output/outbin.c @@ -75,10 +75,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -232,8 +229,7 @@ static void bin_cleanup(void) int h; #ifdef DEBUG - nasm_error(ERR_DEBUG, - "bin_cleanup: Sections were initially referenced in this order:\n"); + nasm_debug("bin_cleanup: Sections were initially referenced in this order:\n"); for (h = 0, s = sections; s; h++, s = s->next) fprintf(stdout, "%i. %s\n", h, s->name); #endif @@ -267,9 +263,8 @@ static void bin_cleanup(void) if (s->flags & (START_DEFINED | ALIGN_DEFINED | FOLLOWS_DEFINED)) { /* Check for a mixture of real and virtual section attributes. */ if (s->flags & (VSTART_DEFINED | VALIGN_DEFINED | VFOLLOWS_DEFINED)) - nasm_fatal(ERR_NOFILE, - "cannot mix real and virtual attributes" - " in nobits section (%s)", s->name); + nasm_fatal("cannot mix real and virtual attributes" + " in nobits section (%s)", s->name); /* Real and virtual attributes mean the same thing for nobits sections. */ if (s->flags & START_DEFINED) { s->vstart = s->start; @@ -338,11 +333,11 @@ static void bin_cleanup(void) s && strcmp(s->name, g->follows); sp = &s->next, s = s->next) ; if (!s) - nasm_fatal(ERR_NOFILE, "section %s follows an invalid or" + nasm_fatal("section %s follows an invalid or" " unknown section (%s)", g->name, g->follows); if (s->next && (s->next->flags & FOLLOWS_DEFINED) && !strcmp(s->name, s->next->follows)) - nasm_fatal(ERR_NOFILE, "sections %s and %s can't both follow" + nasm_fatal("sections %s and %s can't both follow" " section %s", g->name, s->next->name, s->name); /* Find the end of the current follows group (gs). */ for (gsp = &g->next, gs = g->next; @@ -386,7 +381,7 @@ static void bin_cleanup(void) if (sections->flags & START_DEFINED) { /* Make sure this section doesn't begin before the origin. */ if (sections->start < origin) - nasm_fatal(ERR_NOFILE, "section %s begins" + nasm_fatal("section %s begins" " before program origin", sections->name); } else if (sections->flags & ALIGN_DEFINED) { sections->start = ALIGN(origin, sections->align); @@ -442,13 +437,13 @@ static void bin_cleanup(void) /* Check for section overlap. */ if (s) { if (s->start < origin) - nasm_fatal(ERR_NOFILE, "section %s beings before program origin", + nasm_fatal("section %s beings before program origin", s->name); if (g->start > s->start) - nasm_fatal(ERR_NOFILE, "sections %s ~ %s and %s overlap!", + nasm_fatal("sections %s ~ %s and %s overlap!", gs->name, g->name, s->name); if (pend > s->start) - nasm_fatal(ERR_NOFILE, "sections %s and %s overlap!", + nasm_fatal("sections %s and %s overlap!", g->name, s->name); } /* Remember this section as the latest >0 length section. */ @@ -477,9 +472,8 @@ static void bin_cleanup(void) for (s = sections; s && strcmp(g->vfollows, s->name); s = s->next) ; if (!s) - nasm_fatal(ERR_NOFILE, - "section %s vfollows unknown section (%s)", - g->name, g->vfollows); + nasm_fatal("section %s vfollows unknown section (%s)", + g->name, g->vfollows); } else if (g->prev != NULL) for (s = sections; s && (s != g->prev); s = s->next) ; /* The .bss section is the only one with prev = NULL. @@ -510,17 +504,15 @@ static void bin_cleanup(void) for (h = 0, s = sections; s; s = s->next) { if (!(s->flags & VSTART_DEFINED)) { /* Non-fatal errors after assembly has completed are generally a * no-no, but we'll throw a fatal one eventually so it's ok. */ - nasm_error(ERR_NONFATAL, "cannot compute vstart for section %s", - s->name); + nasm_nonfatal("cannot compute vstart for section %s", s->name); h++; } } if (h) - nasm_fatal(ERR_NOFILE, "circular vfollows path detected"); + nasm_fatal("circular vfollows path detected"); #ifdef DEBUG - nasm_error(ERR_DEBUG, - "bin_cleanup: Confirm final section order for output file:\n"); + nasm_debug("bin_cleanup: Confirm final section order for output file:\n"); for (h = 0, s = sections; s && (s->flags & TYPE_PROGBITS); h++, s = s->next) fprintf(stdout, "%i. %s\n", h, s->name); @@ -734,21 +726,13 @@ static void bin_out(int32_t segto, const void *data, if (wrt != NO_SEG) { wrt = NO_SEG; /* continue to do _something_ */ - nasm_error(ERR_NONFATAL, "WRT not supported by binary output format"); - } - - /* Handle absolute-assembly (structure definitions). */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in" - " [ABSOLUTE] space"); - return; + nasm_nonfatal("WRT not supported by binary output format"); } /* Find the segment we are targeting. */ s = find_section_by_index(segto); if (!s) - nasm_panic(0, "code directed to nonexistent segment?"); + nasm_panic("code directed to nonexistent segment?"); /* "Smart" section-type adaptation code. */ if (!(s->flags & TYPE_DEFINED)) { @@ -759,8 +743,8 @@ static void bin_out(int32_t segto, const void *data, } if ((s->flags & TYPE_NOBITS) && (type != OUT_RESERVE)) - nasm_error(ERR_WARNING, "attempt to initialize memory in a" - " nobits section: ignored"); + nasm_warn(WARN_OTHER, "attempt to initialize memory in a" + " nobits section: ignored"); switch (type) { case OUT_ADDRESS: @@ -769,11 +753,11 @@ static void bin_out(int32_t segto, const void *data, if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) - nasm_error(ERR_NONFATAL, "binary output format does not support" - " segment base references"); + nasm_nonfatal("binary output format does not support" + " segment base references"); else - nasm_error(ERR_NONFATAL, "binary output format does not support" - " external references"); + nasm_nonfatal("binary output format does not support" + " external references"); segment = NO_SEG; } if (s->flags & TYPE_PROGBITS) { @@ -799,8 +783,8 @@ static void bin_out(int32_t segto, const void *data, case OUT_RESERVE: if (s->flags & TYPE_PROGBITS) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " %s section: zeroing", s->name); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " %s section: zeroing", s->name); saa_wbytes(s->contents, NULL, size); } break; @@ -814,11 +798,11 @@ static void bin_out(int32_t segto, const void *data, size = realsize(type, size); if (segment != NO_SEG && !find_section_by_index(segment)) { if (segment % 2) - nasm_error(ERR_NONFATAL, "binary output format does not support" - " segment base references"); + nasm_nonfatal("binary output format does not support" + " segment base references"); else - nasm_error(ERR_NONFATAL, "binary output format does not support" - " external references"); + nasm_nonfatal("binary output format does not support" + " external references"); segment = NO_SEG; } if (s->flags & TYPE_PROGBITS) { @@ -831,7 +815,7 @@ static void bin_out(int32_t segto, const void *data, } default: - nasm_error(ERR_NONFATAL, "unsupported relocation type %d\n", type); + nasm_nonfatal("unsupported relocation type %d\n", type); break; } @@ -845,13 +829,13 @@ static void bin_deflabel(char *name, int32_t segment, int64_t offset, (void)offset; /* Don't warn that this parameter is unused */ if (special) - nasm_error(ERR_NONFATAL, "binary format does not support any" - " special symbol types"); + nasm_nonfatal("binary format does not support any" + " special symbol types"); else if (name[0] == '.' && name[1] == '.' && name[2] != '@') - nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_nonfatal("unrecognised special symbol `%s'", name); else if (is_global == 2) - nasm_error(ERR_NONFATAL, "binary output format does not support common" - " variables"); + nasm_nonfatal("binary output format does not support common" + " variables"); else { struct Section *s; struct bin_label ***ltp; @@ -965,14 +949,13 @@ static int bin_read_attribute(char **line, int *attribute, break; } if (!**line) { - nasm_error(ERR_NONFATAL, - "invalid syntax in `section' directive"); + nasm_nonfatal("invalid syntax in `section' directive"); return -1; } ++(*line); } if (!**line) { - nasm_error(ERR_NONFATAL, "expecting `)'"); + nasm_nonfatal("expecting `)'"); return -1; } } @@ -981,8 +964,8 @@ static int bin_read_attribute(char **line, int *attribute, /* Check for no value given. */ if (!*exp) { - nasm_error(ERR_WARNING, "No value given to attribute in" - " `section' directive"); + nasm_warn(WARN_OTHER, "No value given to attribute in" + " `section' directive"); return -1; } @@ -993,13 +976,13 @@ static int bin_read_attribute(char **line, int *attribute, e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL); if (e) { if (!is_really_simple(e)) { - nasm_error(ERR_NONFATAL, "section attribute value must be" - " a critical expression"); + nasm_nonfatal("section attribute value must be" + " a critical expression"); return -1; } } else { - nasm_error(ERR_NONFATAL, "Invalid attribute value" - " specified in `section' directive."); + nasm_nonfatal("Invalid attribute value" + " specified in `section' directive."); return -1; } *value = (uint64_t)reloc_value(e); @@ -1043,8 +1026,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) *astring = '\0'; astring++; } - nasm_error(ERR_WARNING, "ignoring unknown section attribute:" - " \"%s\"", p); + nasm_warn(WARN_OTHER, "ignoring unknown section attribute: \"%s\"", p); } continue; } @@ -1053,9 +1035,8 @@ static void bin_assign_attributes(struct Section *sec, char *astring) case ATTRIB_NOBITS: if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_PROGBITS)) - nasm_error(ERR_NONFATAL, - "attempt to change section type" - " from progbits to nobits"); + nasm_nonfatal("attempt to change section type" + " from progbits to nobits"); else sec->flags |= TYPE_DEFINED | TYPE_NOBITS; continue; @@ -1063,8 +1044,8 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle progbits attribute. */ case ATTRIB_PROGBITS: if ((sec->flags & TYPE_DEFINED) && (sec->flags & TYPE_NOBITS)) - nasm_error(ERR_NONFATAL, "attempt to change section type" - " from nobits to progbits"); + nasm_nonfatal("attempt to change section type" + " from nobits to progbits"); else sec->flags |= TYPE_DEFINED | TYPE_PROGBITS; continue; @@ -1072,8 +1053,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle align attribute. */ case ATTRIB_ALIGN: if (!value || ((value - 1) & value)) { - nasm_error(ERR_NONFATAL, - "argument to `align' is not a power of two"); + nasm_nonfatal("argument to `align' is not a power of two"); } else { /* * Alignment is already satisfied if @@ -1084,8 +1064,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Don't allow a conflicting align value. */ if ((sec->flags & START_DEFINED) && (sec->start & (value - 1))) { - nasm_error(ERR_NONFATAL, - "`align' value conflicts with section start address"); + nasm_nonfatal("`align' value conflicts with section start address"); } else { sec->align = value; sec->flags |= ALIGN_DEFINED; @@ -1096,8 +1075,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle valign attribute. */ case ATTRIB_VALIGN: if (!value || ((value - 1) & value)) - nasm_error(ERR_NONFATAL, "argument to `valign' is not a" - " power of two"); + nasm_nonfatal("argument to `valign' is not a power of two"); else { /* Alignment is already satisfied if the previous * align value is greater. */ if ((sec->flags & VALIGN_DEFINED) && (value < sec->valign)) @@ -1106,9 +1084,7 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Don't allow a conflicting valign value. */ if ((sec->flags & VSTART_DEFINED) && (sec->vstart & (value - 1))) - nasm_error(ERR_NONFATAL, - "`valign' value conflicts " - "with `vstart' address"); + nasm_nonfatal("`valign' value conflicts with `vstart' address"); else { sec->valign = value; sec->flags |= VALIGN_DEFINED; @@ -1119,17 +1095,17 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle start attribute. */ case ATTRIB_START: if (sec->flags & FOLLOWS_DEFINED) - nasm_error(ERR_NONFATAL, "cannot combine `start' and `follows'" - " section attributes"); + nasm_nonfatal("cannot combine `start' and `follows'" + " section attributes"); else if ((sec->flags & START_DEFINED) && (value != sec->start)) - nasm_error(ERR_NONFATAL, "section start address redefined"); + nasm_nonfatal("section start address redefined"); else { sec->start = value; sec->flags |= START_DEFINED; if (sec->flags & ALIGN_DEFINED) { if (sec->start & (sec->align - 1)) - nasm_error(ERR_NONFATAL, "`start' address conflicts" - " with section alignment"); + nasm_nonfatal("`start' address conflicts" + " with section alignment"); sec->flags ^= ALIGN_DEFINED; } } @@ -1138,21 +1114,19 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle vstart attribute. */ case ATTRIB_VSTART: if (sec->flags & VFOLLOWS_DEFINED) - nasm_error(ERR_NONFATAL, - "cannot combine `vstart' and `vfollows'" - " section attributes"); + nasm_nonfatal("cannot combine `vstart' and `vfollows'" + " section attributes"); else if ((sec->flags & VSTART_DEFINED) && (value != sec->vstart)) - nasm_error(ERR_NONFATAL, - "section virtual start address" - " (vstart) redefined"); + nasm_nonfatal("section virtual start address" + " (vstart) redefined"); else { sec->vstart = value; sec->flags |= VSTART_DEFINED; if (sec->flags & VALIGN_DEFINED) { if (sec->vstart & (sec->valign - 1)) - nasm_error(ERR_NONFATAL, "`vstart' address conflicts" - " with `valign' value"); + nasm_nonfatal("`vstart' address conflicts" + " with `valign' value"); sec->flags ^= VALIGN_DEFINED; } } @@ -1163,14 +1137,13 @@ static void bin_assign_attributes(struct Section *sec, char *astring) p = astring; astring += strcspn(astring, " \t"); if (astring == p) - nasm_error(ERR_NONFATAL, "expecting section name for `follows'" - " attribute"); + nasm_nonfatal("expecting section name for `follows'" + " attribute"); else { *(astring++) = '\0'; if (sec->flags & START_DEFINED) - nasm_error(ERR_NONFATAL, - "cannot combine `start' and `follows'" - " section attributes"); + nasm_nonfatal("cannot combine `start' and `follows'" + " section attributes"); sec->follows = nasm_strdup(p); sec->flags |= FOLLOWS_DEFINED; } @@ -1179,16 +1152,14 @@ static void bin_assign_attributes(struct Section *sec, char *astring) /* Handle vfollows attribute. */ case ATTRIB_VFOLLOWS: if (sec->flags & VSTART_DEFINED) - nasm_error(ERR_NONFATAL, - "cannot combine `vstart' and `vfollows'" - " section attributes"); + nasm_nonfatal("cannot combine `vstart' and `vfollows'" + " section attributes"); else { p = astring; astring += strcspn(astring, " \t"); if (astring == p) - nasm_error(ERR_NONFATAL, - "expecting section name for `vfollows'" - " attribute"); + nasm_nonfatal("expecting section name for `vfollows'" + " attribute"); else { *(astring++) = '\0'; sec->vfollows = nasm_strdup(p); @@ -1228,7 +1199,7 @@ static void bin_define_section_labels(void) labels_defined = 1; } -static int32_t bin_secname(char *name, int pass, int *bits) +static int32_t bin_secname(char *name, int *bits) { char *p; struct Section *sec; @@ -1237,14 +1208,15 @@ static int32_t bin_secname(char *name, int pass, int *bits) * pass. Use this opportunity to establish the default section * (default is BITS-16 ".text" segment). */ - if (!name) { /* Reset ORG and section attributes at the start of each pass. */ + if (!name) { + /* Reset ORG and section attributes at the start of each pass. */ origin_defined = 0; list_for_each(sec, sections) sec->flags &= ~(START_DEFINED | VSTART_DEFINED | ALIGN_DEFINED | VALIGN_DEFINED); /* Define section start and vstart labels. */ - if (pass != 1) + if (!pass_first()) bin_define_section_labels(); /* Establish the default (.text) section. */ @@ -1273,14 +1245,14 @@ static int32_t bin_secname(char *name, int pass, int *bits) } /* Handle attribute assignments. */ - if (pass != 1) + if (!pass_first()) bin_assign_attributes(sec, p); #ifndef ABIN_SMART_ADAPT /* The following line disables smart adaptation of * PROGBITS/NOBITS section types (it forces sections to * default to PROGBITS). */ - if ((pass != 1) && !(sec->flags & TYPE_DEFINED)) + if (!pass_first() && !(sec->flags & TYPE_DEFINED)) sec->flags |= TYPE_DEFINED | TYPE_PROGBITS; #endif @@ -1288,7 +1260,7 @@ static int32_t bin_secname(char *name, int pass, int *bits) } static enum directive_result -bin_directive(enum directive directive, char *args, int pass) +bin_directive(enum directive directive, char *args) { switch (directive) { case D_ORG: @@ -1303,21 +1275,21 @@ bin_directive(enum directive directive, char *args, int pass) e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL); if (e) { if (!is_really_simple(e)) - nasm_error(ERR_NONFATAL, "org value must be a critical" + nasm_nonfatal("org value must be a critical" " expression"); else { value = reloc_value(e); /* Check for ORG redefinition. */ if (origin_defined && (value != origin)) - nasm_error(ERR_NONFATAL, "program origin redefined"); + nasm_nonfatal("program origin redefined"); else { origin = value; origin_defined = 1; } } } else - nasm_error(ERR_NONFATAL, "No or invalid offset specified" - " in ORG directive."); + nasm_nonfatal("No or invalid offset specified" + " in ORG directive."); return DIRR_OK; } case D_MAP: @@ -1326,7 +1298,7 @@ bin_directive(enum directive directive, char *args, int pass) * and symbol information to stdout, stderr, or to a file. */ char *p; - if (pass != 1) + if (!pass_first()) return DIRR_OK; args += strspn(args, " \t"); while (*args) { @@ -1353,14 +1325,13 @@ bin_directive(enum directive directive, char *args, int pass) else { /* Must be a filename. */ rf = nasm_open_write(p, NF_TEXT); if (!rf) { - nasm_error(ERR_WARNING, "unable to open map file `%s'", - p); + nasm_warn(WARN_OTHER|ERR_PASS1, "unable to open map file `%s'", p); map_control = 0; return DIRR_OK; } } } else - nasm_error(ERR_WARNING, "map file already specified"); + nasm_warn(WARN_OTHER|ERR_PASS1, "map file already specified"); } if (map_control == 0) map_control |= MAP_ORIGIN | MAP_SUMMARY; @@ -1373,11 +1344,6 @@ bin_directive(enum directive directive, char *args, int pass) } } -static int32_t bin_segbase(int32_t segment) -{ - return segment; -} - const struct ofmt of_bin, of_ith, of_srec; static void binfmt_init(void); static void do_output_bin(void); @@ -1539,7 +1505,7 @@ static void write_srecord(unsigned int len, unsigned int alen, case 4: break; default: - nasm_assert(0); + panic(); break; } @@ -1645,7 +1611,7 @@ const struct ofmt of_bin = { bin_secname, NULL, bin_sectalign, - bin_segbase, + null_segbase, bin_directive, bin_cleanup, NULL /* pragma list */ @@ -1668,7 +1634,7 @@ const struct ofmt of_ith = { bin_secname, NULL, bin_sectalign, - bin_segbase, + null_segbase, bin_directive, bin_cleanup, NULL /* pragma list */ @@ -1691,7 +1657,7 @@ const struct ofmt of_srec = { bin_secname, NULL, bin_sectalign, - bin_segbase, + null_segbase, bin_directive, bin_cleanup, NULL /* pragma list */ diff --git a/output/outcoff.c b/output/outcoff.c index a2fd302c..67bd3ce5 100644 --- a/output/outcoff.c +++ b/output/outcoff.c @@ -38,10 +38,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include <time.h> #include "nasm.h" @@ -291,7 +288,7 @@ static inline int32_t coff_sectalign_flags(unsigned int align) return (ilog2_32(align) + 1) << 20; } -static int32_t coff_section_names(char *name, int pass, int *bits) +static int32_t coff_section_names(char *name, int *bits) { char *p; uint32_t flags, align_and = ~0L, align_or = 0L; @@ -316,8 +313,7 @@ static int32_t coff_section_names(char *name, int pass, int *bits) *p++ = '\0'; if (strlen(name) > 8) { if (!win32 && !win64) { - nasm_error(ERR_WARNING, - "COFF section names limited to 8 characters: truncating"); + nasm_warn(WARN_OTHER, "COFF section names limited to 8 characters: truncating"); name[8] = '\0'; } } @@ -343,8 +339,8 @@ static int32_t coff_section_names(char *name, int pass, int *bits) flags = RDATA_FLAGS; else { flags = DATA_FLAGS; /* gotta do something */ - nasm_error(ERR_NONFATAL, "standard COFF does not support" - " read-only data sections"); + nasm_nonfatal("standard COFF does not support" + " read-only data sections"); } } else if (!nasm_stricmp(q, "bss")) { flags = BSS_FLAGS; @@ -353,25 +349,24 @@ static int32_t coff_section_names(char *name, int pass, int *bits) flags = INFO_FLAGS; else { flags = DATA_FLAGS; /* gotta do something */ - nasm_error(ERR_NONFATAL, "standard COFF does not support" - " informational sections"); + nasm_nonfatal("standard COFF does not support" + " informational sections"); } } else if (!nasm_strnicmp(q, "align=", 6)) { if (!(win32 | win64)) - nasm_error(ERR_NONFATAL, "standard COFF does not support" - " section alignment specification"); + nasm_nonfatal("standard COFF does not support" + " section alignment specification"); else { if (q[6 + strspn(q + 6, "0123456789")]) - nasm_error(ERR_NONFATAL, - "argument to `align' is not numeric"); + nasm_nonfatal("argument to `align' is not numeric"); else { unsigned int align = atoi(q + 6); if (!align || ((align - 1) & align)) - nasm_error(ERR_NONFATAL, "argument to `align' is not a" - " power of two"); + nasm_nonfatal("argument to `align' is not a" + " power of two"); else if (align > 64) - nasm_error(ERR_NONFATAL, "Win32 cannot align sections" - " to better than 64-byte boundaries"); + nasm_nonfatal("Win32 cannot align sections" + " to better than 64-byte boundaries"); else { align_and = ~0x00F00000L; align_or = coff_sectalign_flags(align); @@ -404,45 +399,51 @@ static int32_t coff_section_names(char *name, int pass, int *bits) coff_sects[i]->flags = flags; coff_sects[i]->flags &= align_and; coff_sects[i]->flags |= align_or; - } else if (pass == 1) { - /* Check if any flags are specified */ - if (flags) { - unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK; - - /* Warn if non-alignment flags differ */ - if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK) { - nasm_error(ERR_WARNING, "section attributes ignored on" - " redeclaration of section `%s'", name); + } else if (flags) { + /* Check if any flags are respecified */ + unsigned int align_flags = flags & IMAGE_SCN_ALIGN_MASK; + + /* Warn if non-alignment flags differ */ + if ((flags ^ coff_sects[i]->flags) & ~IMAGE_SCN_ALIGN_MASK && + coff_sects[i]->pass_last_seen == pass_count()) { + nasm_warn(WARN_OTHER, "section attributes changed on" + " redeclaration of section `%s'", name); + } + /* Check if alignment might be needed */ + if (align_flags > IMAGE_SCN_ALIGN_1BYTES) { + unsigned int sect_align_flags = coff_sects[i]->flags & IMAGE_SCN_ALIGN_MASK; + + /* Compute the actual alignment */ + unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20); + + /* Update section header as needed */ + if (align_flags > sect_align_flags) { + coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags; } - /* Check if alignment might be needed */ - if (align_flags > IMAGE_SCN_ALIGN_1BYTES) { - unsigned int sect_align_flags = coff_sects[i]->flags & IMAGE_SCN_ALIGN_MASK; + /* Check if not already aligned */ + if (coff_sects[i]->len % align) { + unsigned int padding = (align - coff_sects[i]->len) % align; + /* We need to write at most 8095 bytes */ + char buffer[8095]; - /* Compute the actual alignment */ - unsigned int align = 1u << ((align_flags - IMAGE_SCN_ALIGN_1BYTES) >> 20); + nasm_assert(padding <= sizeof buffer); - /* Update section header as needed */ - if (align_flags > sect_align_flags) { - coff_sects[i]->flags = (coff_sects[i]->flags & ~IMAGE_SCN_ALIGN_MASK) | align_flags; - } - /* Check if not already aligned */ - if (coff_sects[i]->len % align) { - unsigned int padding = (align - coff_sects[i]->len) % align; - /* We need to write at most 8095 bytes */ - char buffer[8095]; - if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) { - /* Fill with INT 3 instructions */ - memset(buffer, 0xCC, padding); - } else { - memset(buffer, 0x00, padding); - } - saa_wbytes(coff_sects[i]->data, buffer, padding); - coff_sects[i]->len += padding; + if (pass_final()) + nasm_nonfatal("section alignment changed during code generation"); + + if (coff_sects[i]->flags & IMAGE_SCN_CNT_CODE) { + /* Fill with INT 3 instructions */ + memset(buffer, 0xCC, padding); + } else { + memset(buffer, 0x00, padding); } + saa_wbytes(coff_sects[i]->data, buffer, padding); + coff_sects[i]->len += padding; } } } + coff_sects[i]->pass_last_seen = pass_count(); return coff_sects[i]->index; } @@ -453,12 +454,12 @@ static void coff_deflabel(char *name, int32_t segment, int64_t offset, struct coff_Symbol *sym; if (special) - nasm_error(ERR_NONFATAL, "COFF format does not support any" - " special symbol types"); + nasm_nonfatal("COFF format does not support any" + " special symbol types"); if (name[0] == '.' && name[1] == '.' && name[2] != '@') { if (strcmp(name,WRT_IMAGEBASE)) - nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name); + nasm_nonfatal("unrecognized special symbol `%s'", name); return; } @@ -556,17 +557,7 @@ static void coff_out(int32_t segto, const void *data, if (wrt != NO_SEG && !win64) { wrt = NO_SEG; /* continue to do _something_ */ - nasm_error(ERR_NONFATAL, "WRT not supported by COFF output formats"); - } - - /* - * handle absolute-assembly (structure definitions) - */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); - return; + nasm_nonfatal("WRT not supported by COFF output formats"); } s = NULL; @@ -578,8 +569,8 @@ static void coff_out(int32_t segto, const void *data, } if (!s) { int tempint; /* ignored */ - if (segto != coff_section_names(".text", 2, &tempint)) - nasm_panic(0, "strange segment conditions in COFF driver"); + if (segto != coff_section_names(".text", &tempint)) + nasm_panic("strange segment conditions in COFF driver"); else s = coff_sects[coff_nsects - 1]; } @@ -591,8 +582,8 @@ static void coff_out(int32_t segto, const void *data, } if (!s->data && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in" - " BSS section `%s': ignored", s->name); + nasm_warn(WARN_OTHER, "attempt to initialize memory in" + " BSS section `%s': ignored", s->name); s->len += realsize(type, size); return; } @@ -615,30 +606,27 @@ static void coff_out(int32_t segto, const void *data, if (type == OUT_RESERVE) { if (s->data) { - nasm_error(ERR_WARNING, "uninitialised space declared in" - " non-BSS section `%s': zeroing", s->name); + nasm_warn(WARN_ZEROING, "uninitialised space declared in" + " non-BSS section `%s': zeroing", s->name); coff_sect_write(s, NULL, size); } else s->len += size; } else if (type == OUT_RAWDATA) { - if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); coff_sect_write(s, data, size); } else if (type == OUT_ADDRESS) { int asize = abs((int)size); if (!win64) { if (asize != 4 && (segment != NO_SEG || wrt != NO_SEG)) { - nasm_error(ERR_NONFATAL, "COFF format does not support non-32-bit" - " relocations"); + nasm_nonfatal("COFF format does not support non-32-bit" + " relocations"); } else { int32_t fix = 0; if (segment != NO_SEG || wrt != NO_SEG) { if (wrt != NO_SEG) { - nasm_error(ERR_NONFATAL, "COFF format does not support" - " WRT types"); + nasm_nonfatal("COFF format does not support WRT types"); } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "COFF format does not support" - " segment base references"); + nasm_nonfatal("COFF format does not support" + " segment base references"); } else fix = coff_add_reloc(s, segment, IMAGE_REL_I386_DIR32); } @@ -651,8 +639,8 @@ static void coff_out(int32_t segto, const void *data, p = mydata; if (asize == 8) { if (wrt == imagebase_sect) { - nasm_error(ERR_NONFATAL, "operand size mismatch: 'wrt " - WRT_IMAGEBASE "' is a 32-bit operand"); + nasm_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); @@ -666,19 +654,18 @@ static void coff_out(int32_t segto, const void *data, } } } else if (type == OUT_REL2ADR) { - nasm_error(ERR_NONFATAL, "COFF format does not support 16-bit" - " relocations"); + nasm_nonfatal("COFF format does not support 16-bit relocations"); } else if (type == OUT_REL4ADR) { if (segment == segto && !(win64)) /* Acceptable for RIP-relative */ - nasm_panic(0, "intra-segment OUT_REL4ADR"); + nasm_panic("intra-segment OUT_REL4ADR"); else if (segment == NO_SEG && win32) - nasm_error(ERR_NONFATAL, "Win32 COFF does not correctly support" - " relative references to absolute addresses"); + nasm_nonfatal("Win32 COFF does not correctly support" + " relative references to absolute addresses"); else { int32_t fix = 0; if (segment != NO_SEG && segment % 2) { - nasm_error(ERR_NONFATAL, "COFF format does not support" - " segment base references"); + nasm_nonfatal("COFF format does not support" + " segment base references"); } else fix = coff_add_reloc(s, segment, win64 ? IMAGE_REL_AMD64_REL32 : IMAGE_REL_I386_REL32); @@ -767,14 +754,21 @@ static void BuildExportTable(STRING **rvp) } static enum directive_result -coff_directives(enum directive directive, char *value, int pass) +coff_directives(enum directive directive, char *value) { switch (directive) { case D_EXPORT: { char *q, *name; - if (pass == 2) + /* + * XXX: pass_first() is really wrong here, but AddExport() + * needs to be modified to handle duplicate calls for the + * same value in order to change that. The right thing to do + * is probably to mark a label as an export in the label + * structure, in case the label doesn't actually exist. + */ + if (!pass_first()) return DIRR_OK; /* ignore in pass two */ name = q = value; while (*q && !nasm_isspace(*q)) @@ -786,11 +780,11 @@ coff_directives(enum directive directive, char *value, int pass) } if (!*name) { - nasm_error(ERR_NONFATAL, "`export' directive requires export name"); + nasm_nonfatal("`export' directive requires export name"); return DIRR_ERROR; } if (*q) { - nasm_error(ERR_NONFATAL, "unrecognized export qualifier `%s'", q); + nasm_nonfatal("unrecognized export qualifier `%s'", q); return DIRR_ERROR; } AddExport(name); @@ -814,10 +808,10 @@ coff_directives(enum directive directive, char *value, int pass) 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. + * pass_final() is the only time when the full set of symbols are + * guaranteed to be present as it is the final output pass. */ - if (pass0 == 2) { + if (pass_final()) { uint32_t n; saa_rewind(coff_syms); for (n = 0; n < coff_nsyms; n++) { @@ -852,8 +846,7 @@ coff_directives(enum directive directive, char *value, int pass) } } if (n == coff_nsyms) { - nasm_error(ERR_NONFATAL, - "`safeseh' directive requires valid symbol"); + nasm_nonfatal("`safeseh' directive requires valid symbol"); return DIRR_ERROR; } } @@ -873,8 +866,7 @@ static inline void coff_adjust_relocs(struct coff_Section *s) else { if (ofmt == &of_coff) - nasm_fatal(0, - "Too many relocations (%d) for section `%s'", + nasm_fatal("Too many relocations (%d) for section `%s'", s->nrelocs, s->name); } #endif @@ -1135,11 +1127,6 @@ static void coff_sectalign(int32_t seg, unsigned int value) s->flags = (s->flags & ~IMAGE_SCN_ALIGN_MASK) | value; } -static int32_t coff_segbase(int32_t segment) -{ - return segment; -} - extern macros_t coff_stdmac[]; #endif /* defined(OF_COFF) || defined(OF_WIN32) */ @@ -1163,7 +1150,7 @@ const struct ofmt of_coff = { coff_section_names, NULL, coff_sectalign, - coff_segbase, + null_segbase, coff_directives, coff_cleanup, NULL /* pragma list */ @@ -1194,7 +1181,7 @@ const struct ofmt of_win32 = { coff_section_names, NULL, coff_sectalign, - coff_segbase, + null_segbase, coff_directives, coff_cleanup, NULL /* pragma list */ @@ -1223,7 +1210,7 @@ const struct ofmt of_win64 = { coff_section_names, NULL, coff_sectalign, - coff_segbase, + null_segbase, coff_directives, coff_cleanup, NULL /* pragma list */ diff --git a/output/outdbg.c b/output/outdbg.c index fdf35aa2..2bf176cb 100644 --- a/output/outdbg.c +++ b/output/outdbg.c @@ -38,10 +38,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include <errno.h> #include "nasm.h" @@ -75,8 +72,8 @@ static void dbg_init(void) static void dbg_reset(void) { - fprintf(ofile, "*** pass reset: pass0 = %d, passn = %"PRId64"\n", - pass0, passn); + fprintf(ofile, "*** pass reset: pass = %"PRId64" (%s)\n", + pass_count(), pass_type_name()); } static void dbg_cleanup(void) @@ -90,8 +87,7 @@ static void dbg_cleanup(void) } } -static int32_t dbg_add_section(char *name, int pass, int *bits, - const char *whatwecallit) +static int32_t dbg_add_section(char *name, int *bits, const char *whatwecallit) { int seg; @@ -121,8 +117,8 @@ static int32_t dbg_add_section(char *name, int pass, int *bits, s->number = seg = seg_alloc(); s->next = dbgsect; dbgsect = s; - fprintf(ofile, "%s %s (%s) pass %d: returning %d\n", - whatwecallit, name, tail, pass, seg); + fprintf(ofile, "%s %s (%s) pass %"PRId64" (%s) : returning %d\n", + whatwecallit, name, tail, pass_count(), pass_type_name(), seg); if (section_labels) backend_label(s->name, s->number + 1, 0); @@ -131,9 +127,9 @@ static int32_t dbg_add_section(char *name, int pass, int *bits, return seg; } -static int32_t dbg_section_names(char *name, int pass, int *bits) +static int32_t dbg_section_names(char *name, int *bits) { - return dbg_add_section(name, pass, bits, "section_names"); + return dbg_add_section(name, bits, "section_names"); } static int32_t dbg_herelabel(const char *name, enum label_type type, @@ -322,13 +318,8 @@ static void dbg_sectalign(int32_t seg, unsigned int value) seg, value); } -static int32_t dbg_segbase(int32_t segment) -{ - return segment; -} - static enum directive_result -dbg_directive(enum directive directive, char *value, int pass) +dbg_directive(enum directive directive, char *value) { switch (directive) { /* @@ -339,7 +330,7 @@ dbg_directive(enum directive directive, char *value, int pass) case D_GROUP: { int dummy; - dbg_add_section(value, pass, &dummy, "directive:group"); + dbg_add_section(value, &dummy, "directive:group"); break; } @@ -347,8 +338,8 @@ dbg_directive(enum directive directive, char *value, int pass) break; } - fprintf(ofile, "directive [%s] value [%s] (pass %d)\n", - directive_dname(directive), value, pass); + fprintf(ofile, "directive [%s] value [%s] pass %"PRId64" (%s)\n", + directive_dname(directive), value, pass_count(), pass_type_name()); return DIRR_OK; } @@ -484,7 +475,7 @@ const struct ofmt of_dbg = { dbg_section_names, dbg_herelabel, dbg_sectalign, - dbg_segbase, + null_segbase, dbg_directive, dbg_cleanup, dbg_pragma_list diff --git a/output/outelf.c b/output/outelf.c index 36531d3a..c176689d 100644 --- a/output/outelf.c +++ b/output/outelf.c @@ -37,8 +37,6 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> #include "nasm.h" #include "nasmlib.h" @@ -80,7 +78,7 @@ static struct SAA *symtab, *symtab_shndx; static struct SAA *strs; static uint32_t strslen; -static struct RAAPTR *section_by_index; +static struct RAA *section_by_index; static struct hash_table section_by_name; static struct elf_symbol *fwds; @@ -296,8 +294,7 @@ static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint while ((opt = nasm_opt_val(opt, &val, &next))) { if (!nasm_stricmp(opt, "align")) { if (!val) { - nasm_error(ERR_NONFATAL, - "section align without value specified"); + nasm_nonfatal("section align without value specified"); } else { bool err; uint64_t a = readnum(val, &err); @@ -383,11 +380,11 @@ static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint xalign = to_bytes(su->align); } else { /* Unknown attribute */ - nasm_error(ERR_WARNING|ERR_PASS1, + nasm_warn(WARN_OTHER, "unknown section attribute '%s' ignored on" " declaration of section `%s'", opt, name); } - } + } opt = next; } @@ -413,7 +410,7 @@ static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint } static enum directive_result -elf_directive(enum directive directive, char *value, int pass) +elf_directive(enum directive directive, char *value) { int64_t n; bool err; @@ -421,17 +418,17 @@ elf_directive(enum directive directive, char *value, int pass) switch (directive) { case D_OSABI: - if (pass == 2) - return DIRR_OK; /* ignore in pass 2 */ + if (!pass_first()) /* XXX: Why? */ + return DIRR_OK; n = readnum(value, &err); if (err) { - nasm_error(ERR_NONFATAL, "`osabi' directive requires a parameter"); + nasm_nonfatal("`osabi' directive requires a parameter"); return DIRR_ERROR; } if (n < 0 || n > 255) { - nasm_error(ERR_NONFATAL, "valid osabi numbers are 0 to 255"); + nasm_nonfatal("valid osabi numbers are 0 to 255"); return DIRR_ERROR; } @@ -444,7 +441,7 @@ elf_directive(enum directive directive, char *value, int pass) n = readnum(p + 1, &err); if (err || n < 0 || n > 255) { - nasm_error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)"); + nasm_nonfatal("invalid ABI version number (valid: 0 to 255)"); return DIRR_ERROR; } @@ -547,8 +544,7 @@ static void elf_init(void) fwds = NULL; - hash_init(§ion_by_name, HASH_MEDIUM); - section_by_index = raa_init_ptr(); + section_by_index = raa_init(); /* * Add reserved section names to the section hash, with NULL @@ -600,7 +596,7 @@ static void elf_cleanup(void) } } hash_free(§ion_by_name); - raa_free_ptr(section_by_index); + raa_free(section_by_index); nasm_free(sects); saa_free(syms); raa_free(bsym); @@ -659,7 +655,7 @@ elf_make_section(char *name, int type, int flags, uint64_t align) return s; } -static int32_t elf_section_names(char *name, int pass, int *bits) +static int32_t elf_section_names(char *name, int *bits) { char *p; uint32_t flags, flags_and, flags_or; @@ -669,8 +665,6 @@ static int32_t elf_section_names(char *name, int pass, int *bits) struct hash_insert hi; int type; - (void)pass; - if (!name) { *bits = ofmt->maxbits; return def_seg; @@ -687,8 +681,7 @@ static int32_t elf_section_names(char *name, int pass, int *bits) if (hp) { s = *hp; if (!s) { - nasm_error(ERR_NONFATAL, "attempt to redefine reserved section" - "name `%s'", name); + nasm_nonfatal("attempt to redefine reserved section name `%s'", name); return NO_SEG; } } else { @@ -712,14 +705,11 @@ static int32_t elf_section_names(char *name, int pass, int *bits) section_by_index = raa_write_ptr(section_by_index, s->index >> 1, s); } - if (pass == 1) { - if ((type && s->type != type) - || ((s->flags & flags_and) != flags_or) - || (entsize && s->entsize && entsize != s->entsize)) { - nasm_error(ERR_WARNING, - "incompatible section attributes ignored on" - " redeclaration of section `%s'", name); - } + if ((type && s->type != type) + || ((s->flags & flags_and) != flags_or) + || (entsize && s->entsize && entsize != s->entsize)) { + nasm_warn(WARN_OTHER, "incompatible section attributes ignored on" + " redeclaration of section `%s'", name); } if (align > s->align) @@ -728,10 +718,9 @@ static int32_t elf_section_names(char *name, int pass, int *bits) if (entsize && !s->entsize) s->entsize = entsize; - if (pass == 2 && (flags_or & SHF_MERGE) && s->entsize == 0) { + if ((flags_or & SHF_MERGE) && s->entsize == 0) { if (!(s->flags & SHF_STRINGS)) - nasm_error(ERR_NONFATAL, - "section attribute merge specified without an entry size"); + nasm_nonfatal("section attribute merge specified without an entry size or `strings'"); s->entsize = 1; } @@ -746,9 +735,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, bool special_used = false; #if defined(DEBUG) && DEBUG>2 - nasm_error(ERR_DEBUG, - " elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", - name, segment, offset, is_global, special); + nasm_debug(" elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", + name, segment, offset, is_global, special); #endif if (name[0] == '.' && name[1] == '.' && name[2] != '@') { /* @@ -762,7 +750,7 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, strcmp(name, "..got") && strcmp(name, "..plt") && strcmp(name, "..sym") && strcmp(name, "..gottpoff") && strcmp(name, "..tlsie")) - nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_nonfatal("unrecognised special symbol `%s'", name); return; } @@ -784,8 +772,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL); if (e) { if (!is_simple(e)) - nasm_error(ERR_NONFATAL, "cannot use relocatable" - " expression as symbol size"); + nasm_nonfatal("cannot use relocatable" + " expression as symbol size"); else (*s)->size = reloc_value(e); } @@ -819,8 +807,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, if (segment == def_seg) { /* we have to be sure at least text section is there */ int tempint; - if (segment != elf_section_names(".text", 2, &tempint)) - nasm_panic(0, "strange segment conditions in ELF driver"); + if (segment != elf_section_names(".text", &tempint)) + nasm_panic("strange segment conditions in ELF driver"); } s = raa_read_ptr(section_by_index, segment >> 1); if (s) @@ -840,11 +828,11 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, bool err; sym->symv.key = readnum(special, &err); if (err) - nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a" - " valid number", special); + nasm_nonfatal("alignment constraint `%s' is not a" + " valid number", special); else if ((sym->symv.key | (sym->symv.key - 1)) != 2 * sym->symv.key - 1) - nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a" - " power of two", special); + nasm_nonfatal("alignment constraint `%s' is not a" + " power of two", special); } special_used = true; } else @@ -885,8 +873,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, else if (!nasm_strnicmp(special, "notype", n)) sym->type |= STT_NOTYPE; else - nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'", - n, special); + nasm_nonfatal("unrecognised symbol type `%.*s'", + n, special); special += n; special = nasm_skip_spaces(special); @@ -927,8 +915,8 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, sym->name = nasm_strdup(name); } else if (e) { if (!is_simple(e)) - nasm_error(ERR_NONFATAL, "cannot use relocatable" - " expression as symbol size"); + nasm_nonfatal("cannot use relocatable" + " expression as symbol size"); else sym->size = reloc_value(e); } @@ -950,7 +938,7 @@ static void elf_deflabel(char *name, int32_t segment, int64_t offset, nlocals++; if (special && !special_used) - nasm_error(ERR_NONFATAL, "no special symbol features supported here"); + nasm_nonfatal("no special symbol features supported here"); } static void elf_add_reloc(struct elf_section *sect, int32_t segment, @@ -1018,7 +1006,7 @@ static int64_t elf_add_gsym_reloc(struct elf_section *sect, s = raa_read_ptr(section_by_index, segment >> 1); if (!s) { if (exact && offset) - nasm_error(ERR_NONFATAL, "invalid access to an external symbol"); + nasm_nonfatal("invalid access to an external symbol"); else elf_add_reloc(sect, segment, offset - pcrel, type); return 0; @@ -1026,8 +1014,8 @@ static int64_t elf_add_gsym_reloc(struct elf_section *sect, srb = rb_search(s->gsyms, offset); if (!srb || (exact && srb->key != offset)) { - nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol" - " for this reference"); + nasm_nonfatal("unable to find a suitable global symbol" + " for this reference"); return 0; } sym = container_of(srb, struct elf_symbol, symv); @@ -1059,16 +1047,15 @@ static void elf32_out(int32_t segto, const void *data, */ if (segto == NO_SEG) { if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); + nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space"); return; } s = raa_read_ptr(section_by_index, segto >> 1); if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) - nasm_panic(0, "strange segment conditions in ELF driver"); + if (segto != elf_section_names(".text", &tempint)) + nasm_panic("strange segment conditions in ELF driver"); else s = sects[nsects - 1]; } @@ -1082,8 +1069,8 @@ static void elf32_out(int32_t segto, const void *data, /* end of debugging stuff */ if (s->type == SHT_NOBITS && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in" - " BSS section `%s': ignored", s->name); + nasm_warn(WARN_OTHER, "attempt to initialize memory in" + " BSS section `%s': ignored", s->name); s->len += realsize(type, size); return; } @@ -1091,16 +1078,14 @@ static void elf32_out(int32_t segto, const void *data, switch (type) { case OUT_RESERVE: if (s->type != SHT_NOBITS) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " non-BSS section `%s': zeroing", s->name); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " non-BSS section `%s': zeroing", s->name); elf_sect_write(s, NULL, size); } else s->len += size; break; case OUT_RAWDATA: - if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); elf_sect_write(s, data, size); break; @@ -1112,8 +1097,8 @@ static void elf32_out(int32_t segto, const void *data, addr = *(int64_t *)data; if (segment != NO_SEG) { if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { /* @@ -1172,21 +1157,26 @@ static void elf32_out(int32_t segto, const void *data, break; } } else if (wrt == elf_plt_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-" - "relative PLT references"); + nasm_nonfatal("ELF format cannot produce non-PC-" + "relative PLT references"); } else { - nasm_error(ERR_NONFATAL, "ELF format does not support this" - " use of WRT"); + nasm_nonfatal("ELF format does not support this" + " use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } } } if (gnu16) { - nasm_error(ERR_WARNING | WARN_GNUELF, - "8- or 16-bit relocations in ELF32 is a GNU extension"); + /*! + *!gnu-elf-extensions [off] using 8- or 16-bit relocation in ELF32, a GNU extension + *! warns if 8-bit or 16-bit relocations are used in the \c{elf32} output format. + *! The GNU extensions allow this. + */ + nasm_warn(WARN_GNU_ELF_EXTENSIONS, "8- or 16-bit relocations " + "in ELF32 is a GNU extension"); } else if (asize != 4 && segment != NO_SEG) { - nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation"); + nasm_nonfatal("Unsupported non-32-bit ELF relocation"); } elf_sect_writeaddr(s, addr, asize); break; @@ -1205,16 +1195,15 @@ rel12adr: addr = *(int64_t *)data - size; nasm_assert(segment != segto); if (segment != NO_SEG && segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { - nasm_error(ERR_WARNING | WARN_GNUELF, - "8- or 16-bit relocations in ELF is a GNU extension"); + nasm_warn(WARN_GNU_ELF_EXTENSIONS, "8- or 16-bit relocations " + "in ELF is a GNU extension"); elf_add_reloc(s, segment, 0, reltype); } else { - nasm_error(ERR_NONFATAL, - "Unsupported non-32-bit ELF relocation"); + nasm_nonfatal("Unsupported non-32-bit ELF relocation"); } } elf_sect_writeaddr(s, addr, bytes); @@ -1223,10 +1212,10 @@ rel12adr: case OUT_REL4ADR: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL4ADR"); + nasm_panic("intra-segment OUT_REL4ADR"); if (segment != NO_SEG && segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, 0, R_386_PC32); @@ -1235,11 +1224,11 @@ rel12adr: } else if (wrt == elf_gotpc_sect + 1 || wrt == elf_gotoff_sect + 1 || wrt == elf_got_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF format cannot produce PC-" - "relative GOT references"); + nasm_nonfatal("ELF format cannot produce PC-" + "relative GOT references"); } else { - nasm_error(ERR_NONFATAL, "ELF format does not support this" - " use of WRT"); + nasm_nonfatal("ELF format does not support this" + " use of WRT"); wrt = NO_SEG; /* we can at least _try_ to continue */ } } @@ -1247,7 +1236,7 @@ rel12adr: break; case OUT_REL8ADR: - nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations"); + nasm_nonfatal("32-bit ELF format does not support 64-bit relocations"); addr = 0; elf_sect_writeaddr(s, addr, 8); break; @@ -1270,16 +1259,15 @@ static void elf64_out(int32_t segto, const void *data, */ if (segto == NO_SEG) { if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); + nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space"); return; } s = raa_read_ptr(section_by_index, segto >> 1); if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) - nasm_panic(0, "strange segment conditions in ELF driver"); + if (segto != elf_section_names(".text", &tempint)) + nasm_panic("strange segment conditions in ELF driver"); else s = sects[nsects - 1]; } @@ -1293,8 +1281,8 @@ static void elf64_out(int32_t segto, const void *data, /* end of debugging stuff */ if (s->type == SHT_NOBITS && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in" - " BSS section `%s': ignored", s->name); + nasm_warn(WARN_OTHER, "attempt to initialize memory in" + " BSS section `%s': ignored", s->name); s->len += realsize(type, size); return; } @@ -1302,8 +1290,8 @@ static void elf64_out(int32_t segto, const void *data, switch (type) { case OUT_RESERVE: if (s->type != SHT_NOBITS) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " non-BSS section `%s': zeroing", s->name); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " non-BSS section `%s': zeroing", s->name); elf_sect_write(s, NULL, size); } else s->len += size; @@ -1311,7 +1299,7 @@ static void elf64_out(int32_t segto, const void *data, case OUT_RAWDATA: if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); + nasm_panic("OUT_RAWDATA with other than NO_SEG"); elf_sect_write(s, data, size); break; @@ -1324,8 +1312,8 @@ static void elf64_out(int32_t segto, const void *data, if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { switch (isize) { @@ -1348,7 +1336,7 @@ static void elf64_out(int32_t segto, const void *data, elf_add_reloc(s, segment, addr, R_X86_64_64); break; default: - nasm_panic(0, "internal error elf64-hpa-871"); + nasm_panic("internal error elf64-hpa-871"); break; } addr = 0; @@ -1363,8 +1351,8 @@ static void elf64_out(int32_t segto, const void *data, addr = 0; } else if (wrt == elf_gotoff_sect + 1) { if (asize != 8) { - nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff " - "references to be qword"); + nasm_nonfatal("ELF64 requires ..gotoff " + "references to be qword"); } else { elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64); addr = 0; @@ -1382,7 +1370,7 @@ static void elf64_out(int32_t segto, const void *data, addr = 0; break; default: - nasm_error(ERR_NONFATAL, "invalid ..got reference"); + nasm_nonfatal("invalid ..got reference"); break; } } else if (wrt == elf_sym_sect + 1) { @@ -1416,15 +1404,15 @@ static void elf64_out(int32_t segto, const void *data, addr = 0; break; default: - nasm_panic(0, "internal error elf64-hpa-903"); + nasm_panic("internal error elf64-hpa-903"); break; } } else if (wrt == elf_plt_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-" - "relative PLT references"); + nasm_nonfatal("ELF format cannot produce non-PC-" + "relative PLT references"); } else { - nasm_error(ERR_NONFATAL, "ELF format does not support this" - " use of WRT"); + nasm_nonfatal("ELF format does not support this" + " use of WRT"); } } elf_sect_writeaddr(s, addr, asize); @@ -1444,20 +1432,18 @@ static void elf64_out(int32_t segto, const void *data, rel12adr: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL1ADR"); + nasm_panic("intra-segment OUT_REL1ADR"); if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, addr, reltype); addr = 0; - } else { - nasm_error(ERR_NONFATAL, - "Unsupported non-32-bit ELF relocation"); - } + } else + nasm_nonfatal("Unsupported non-32-bit ELF relocation"); } elf_sect_writeaddr(s, addr, bytes); break; @@ -1465,12 +1451,12 @@ rel12adr: case OUT_REL4ADR: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL4ADR"); + nasm_panic("intra-segment OUT_REL4ADR"); if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF64 format does not support" - " segment base references"); + nasm_nonfatal("ELF64 format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, addr, R_X86_64_PC32); @@ -1486,15 +1472,15 @@ rel12adr: addr = 0; } else if (wrt == elf_gotoff_sect + 1 || wrt == elf_got_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be " - "qword absolute"); + nasm_nonfatal("ELF64 requires ..gotoff references to be " + "qword absolute"); } else if (wrt == elf_gottpoff_sect + 1) { elf_add_gsym_reloc(s, segment, addr+size, size, R_X86_64_GOTTPOFF, true); addr = 0; } else { - nasm_error(ERR_NONFATAL, "ELF64 format does not support this" - " use of WRT"); + nasm_nonfatal("ELF64 format does not support this" + " use of WRT"); } } elf_sect_writeaddr(s, addr, 4); @@ -1503,12 +1489,12 @@ rel12adr: case OUT_REL8ADR: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL8ADR"); + nasm_panic("intra-segment OUT_REL8ADR"); if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF64 format does not support" - " segment base references"); + nasm_nonfatal("ELF64 format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, addr, R_X86_64_PC64); @@ -1520,14 +1506,14 @@ rel12adr: addr = 0; } else if (wrt == elf_gotoff_sect + 1 || wrt == elf_got_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be " - "absolute"); + nasm_nonfatal("ELF64 requires ..gotoff references to be " + "absolute"); } else if (wrt == elf_gottpoff_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF64 requires ..gottpoff references to be " - "dword"); + nasm_nonfatal("ELF64 requires ..gottpoff references to be " + "dword"); } else { - nasm_error(ERR_NONFATAL, "ELF64 format does not support this" - " use of WRT"); + nasm_nonfatal("ELF64 format does not support this" + " use of WRT"); } } elf_sect_writeaddr(s, addr, 8); @@ -1552,16 +1538,15 @@ static void elfx32_out(int32_t segto, const void *data, */ if (segto == NO_SEG) { if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); + nasm_nonfatal("attempt to assemble code in [ABSOLUTE] space"); return; } s = raa_read_ptr(section_by_index, segto >> 1); if (!s) { int tempint; /* ignored */ - if (segto != elf_section_names(".text", 2, &tempint)) - nasm_panic(0, "strange segment conditions in ELF driver"); + if (segto != elf_section_names(".text", &tempint)) + nasm_panic("strange segment conditions in ELF driver"); else s = sects[nsects - 1]; } @@ -1575,8 +1560,8 @@ static void elfx32_out(int32_t segto, const void *data, /* end of debugging stuff */ if (s->type == SHT_NOBITS && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in" - " BSS section `%s': ignored", s->name); + nasm_warn(WARN_OTHER, "attempt to initialize memory in" + " BSS section `%s': ignored", s->name); s->len += realsize(type, size); return; } @@ -1584,8 +1569,8 @@ static void elfx32_out(int32_t segto, const void *data, switch (type) { case OUT_RESERVE: if (s->type != SHT_NOBITS) { - nasm_error(ERR_WARNING, "uninitialized space declared in" - " non-BSS section `%s': zeroing", s->name); + nasm_warn(WARN_ZEROING, "uninitialized space declared in" + " non-BSS section `%s': zeroing", s->name); elf_sect_write(s, NULL, size); } else s->len += size; @@ -1593,7 +1578,7 @@ static void elfx32_out(int32_t segto, const void *data, case OUT_RAWDATA: if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); + nasm_panic("OUT_RAWDATA with other than NO_SEG"); elf_sect_write(s, data, size); break; @@ -1606,8 +1591,8 @@ static void elfx32_out(int32_t segto, const void *data, if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { switch (isize) { @@ -1630,7 +1615,7 @@ static void elfx32_out(int32_t segto, const void *data, elf_add_reloc(s, segment, addr, R_X86_64_64); break; default: - nasm_panic(0, "internal error elfx32-hpa-871"); + nasm_panic("internal error elfx32-hpa-871"); break; } addr = 0; @@ -1644,8 +1629,8 @@ static void elfx32_out(int32_t segto, const void *data, elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32); addr = 0; } else if (wrt == elf_gotoff_sect + 1) { - nasm_error(ERR_NONFATAL, "ELFX32 doesn't support " - "R_X86_64_GOTOFF64"); + nasm_nonfatal("ELFX32 doesn't support " + "R_X86_64_GOTOFF64"); } else if (wrt == elf_got_sect + 1) { switch (asize) { case 4: @@ -1654,7 +1639,7 @@ static void elfx32_out(int32_t segto, const void *data, addr = 0; break; default: - nasm_error(ERR_NONFATAL, "invalid ..got reference"); + nasm_nonfatal("invalid ..got reference"); break; } } else if (wrt == elf_sym_sect + 1) { @@ -1688,15 +1673,15 @@ static void elfx32_out(int32_t segto, const void *data, addr = 0; break; default: - nasm_panic(0, "internal error elfx32-hpa-903"); + nasm_panic("internal error elfx32-hpa-903"); break; } } else if (wrt == elf_plt_sect + 1) { - nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-" - "relative PLT references"); + nasm_nonfatal("ELF format cannot produce non-PC-" + "relative PLT references"); } else { - nasm_error(ERR_NONFATAL, "ELF format does not support this" - " use of WRT"); + nasm_nonfatal("ELF format does not support this" + " use of WRT"); } } elf_sect_writeaddr(s, addr, asize); @@ -1716,20 +1701,18 @@ static void elfx32_out(int32_t segto, const void *data, rel12adr: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL1ADR"); + nasm_panic("intra-segment OUT_REL1ADR"); if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELF format does not support" - " segment base references"); + nasm_nonfatal("ELF format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, addr, reltype); addr = 0; - } else { - nasm_error(ERR_NONFATAL, - "Unsupported non-32-bit ELF relocation"); - } + } else + nasm_nonfatal("Unsupported non-32-bit ELF relocation"); } elf_sect_writeaddr(s, addr, bytes); break; @@ -1737,12 +1720,12 @@ rel12adr: case OUT_REL4ADR: addr = *(int64_t *)data - size; if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL4ADR"); + nasm_panic("intra-segment OUT_REL4ADR"); if (segment == NO_SEG) { /* Do nothing */ } else if (segment % 2) { - nasm_error(ERR_NONFATAL, "ELFX32 format does not support" - " segment base references"); + nasm_nonfatal("ELFX32 format does not support" + " segment base references"); } else { if (wrt == NO_SEG) { elf_add_reloc(s, segment, addr, R_X86_64_PC32); @@ -1758,21 +1741,20 @@ rel12adr: addr = 0; } else if (wrt == elf_gotoff_sect + 1 || wrt == elf_got_sect + 1) { - nasm_error(ERR_NONFATAL, "invalid ..gotoff reference"); + nasm_nonfatal("invalid ..gotoff reference"); } else if (wrt == elf_gottpoff_sect + 1) { elf_add_gsym_reloc(s, segment, addr+size, size, R_X86_64_GOTTPOFF, true); addr = 0; } else { - nasm_error(ERR_NONFATAL, "ELFX32 format does not support this" - " use of WRT"); + nasm_nonfatal("ELFX32 format does not support this use of WRT"); } } elf_sect_writeaddr(s, addr, 4); break; case OUT_REL8ADR: - nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations"); + nasm_nonfatal("32-bit ELF format does not support 64-bit relocations"); addr = 0; elf_sect_writeaddr(s, addr, 8); break; @@ -2369,11 +2351,6 @@ static void elf_sectalign(int32_t seg, unsigned int value) s->align = value; } -static int32_t elf_segbase(int32_t segment) -{ - return segment; -} - extern macros_t elf_stdmac[]; /* Claim "elf" as a pragma namespace, for the future */ @@ -2430,7 +2407,7 @@ const struct ofmt of_elf32 = { elf_section_names, NULL, elf_sectalign, - elf_segbase, + null_segbase, elf_directive, elf_cleanup, elf_pragma_list, @@ -2482,7 +2459,7 @@ const struct ofmt of_elf64 = { elf_section_names, NULL, elf_sectalign, - elf_segbase, + null_segbase, elf_directive, elf_cleanup, elf_pragma_list, @@ -2534,7 +2511,7 @@ const struct ofmt of_elfx32 = { elf_section_names, NULL, elf_sectalign, - elf_segbase, + null_segbase, elf_directive, elf_cleanup, NULL /* pragma list */ @@ -3182,7 +3159,7 @@ static void dwarf_generate(void) saa_write32(pinforel, 0); saa_write32(pinfo,0); /* DW_AT_stmt_list */ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1); - saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1); + saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1); saa_write16(pinfo,DW_LANG_Mips_Assembler); saa_write8(pinfo,2); /* abbrviation number LEB128u */ saa_write32(pinforel, pinfo->datalen + 4); @@ -3221,7 +3198,7 @@ static void dwarf_generate(void) saa_write32(pinforel, 0); saa_write32(pinfo,0); /* DW_AT_stmt_list */ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1); - saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1); + saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1); saa_write16(pinfo,DW_LANG_Mips_Assembler); saa_write8(pinfo,2); /* abbrviation number LEB128u */ saa_write32(pinforel, pinfo->datalen + 4); @@ -3261,7 +3238,7 @@ static void dwarf_generate(void) saa_write64(pinforel, 0); saa_write32(pinfo,0); /* DW_AT_stmt_list */ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1); - saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1); + saa_wbytes(pinfo, nasm_signature(), nasm_signature_len()+1); saa_write16(pinfo,DW_LANG_Mips_Assembler); saa_write8(pinfo,2); /* abbrviation number LEB128u */ saa_write64(pinforel, pinfo->datalen + 4); diff --git a/output/outelf.h b/output/outelf.h index af6af070..f5ccfe1c 100644 --- a/output/outelf.h +++ b/output/outelf.h @@ -125,6 +125,7 @@ struct elf_section { int type; /* SHT_* */ uint64_t align; /* alignment: power of two */ uint64_t flags; /* section flags */ + int64_t pass_last_seen; uint64_t entsize; /* entry size */ char *name; struct SAA *rel; diff --git a/output/outform.c b/output/outform.c index f227be43..d299d04a 100644 --- a/output/outform.c +++ b/output/outform.c @@ -40,8 +40,6 @@ #include "compiler.h" -#include <stdio.h> -#include <string.h> #define BUILD_DRIVERS_ARRAY #include "outform.h" diff --git a/output/outieee.c b/output/outieee.c index 3a28942d..4cc0f0f5 100644 --- a/output/outieee.c +++ b/output/outieee.c @@ -67,12 +67,9 @@ */ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <time.h> -#include <stdarg.h> /* Note: we need the ANSI version of stdarg.h */ -#include <ctype.h> +#include <ctype.h> /* For toupper() */ +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -146,11 +143,12 @@ static struct ieeeSection { struct ieeeObjData *data, *datacurr; struct ieeeFixupp *fptr, *flptr; int32_t index; /* the NASM segment id */ - int32_t ieee_index; /* the OBJ-file segment index */ + int32_t ieee_index; /* the IEEE-file segment index */ int32_t currentpos; int32_t align; /* can be SEG_ABS + absolute addr */ int32_t startpos; int32_t use32; /* is this segment 32-bit? */ + int64_t pass_last_seen; struct ieeePublic *pubhead, **pubtail, *lochead, **loctail; enum { CMB_PRIVATE = 0, @@ -193,7 +191,7 @@ static void ieee_data_new(struct ieeeSection *); static void ieee_write_fixup(int32_t, int32_t, struct ieeeSection *, int, uint64_t, int32_t); static void ieee_install_fixup(struct ieeeSection *, struct ieeeFixupp *); -static int32_t ieee_segment(char *, int, int *); +static int32_t ieee_segment(char *, int *); static void ieee_write_file(void); static void ieee_write_byte(struct ieeeSection *, int); static void ieee_write_word(struct ieeeSection *, int); @@ -294,9 +292,8 @@ static void ieee_deflabel(char *name, int32_t segment, struct ieeeSection *seg; int i; - if (special) { - nasm_error(ERR_NONFATAL, "unrecognised symbol type `%s'", special); - } + if (special) + nasm_nonfatal("unrecognised symbol type `%s'", special); /* * First check for the double-period, signifying something * unusual. @@ -399,23 +396,13 @@ static void ieee_out(int32_t segto, const void *data, struct ieeeSection *seg; /* - * handle absolute-assembly (structure definitions) - */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); - return; - } - - /* * If `any_segs' is still false, we must define a default * segment. */ if (!any_segs) { int tempint; /* ignored */ - if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic(0, "strange segment conditions in IEEE driver"); + if (segto != ieee_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in IEEE driver"); } /* @@ -425,7 +412,7 @@ static void ieee_out(int32_t segto, const void *data, if (seg->index == segto) break; if (!seg) - nasm_panic(0, "code directed to nonexistent segment?"); + nasm_panic("code directed to nonexistent segment?"); if (type == OUT_RAWDATA) { ucdata = data; @@ -436,8 +423,8 @@ static void ieee_out(int32_t segto, const void *data, if (type == OUT_ADDRESS) size = abs((int)size); else if (segment == NO_SEG) - nasm_error(ERR_NONFATAL, "relative call to absolute address not" - " supported by IEEE format"); + nasm_nonfatal("relative call to absolute address not" + " supported by IEEE format"); ldata = *(int64_t *)data; if (type == OUT_REL2ADR) ldata += (size - 2); @@ -526,15 +513,13 @@ static void ieee_write_fixup(int32_t segment, int32_t wrt, s.addend = 0; s.id2 = eb->index[i]; } else - nasm_error(ERR_NONFATAL, - "Source of WRT must be an offset"); + nasm_nonfatal("source of WRT must be an offset"); } } else - nasm_panic(0, - "unrecognised WRT value in ieee_write_fixup"); + nasm_panic("unrecognised WRT value in ieee_write_fixup"); } else - nasm_error(ERR_NONFATAL, "target of WRT must be a section "); + nasm_nonfatal("target of WRT must be a section"); } s.size = size; ieee_install_fixup(segto, &s); @@ -573,8 +558,7 @@ static void ieee_write_fixup(int32_t segment, int32_t wrt, */ if (eb) { if (realtype == OUT_REL2ADR || realtype == OUT_REL4ADR) { - nasm_panic(0, - "Segment of a rel not supported in ieee_write_fixup"); + nasm_panic("Segment of a rel not supported in ieee_write_fixup"); } else { /* If we want the segment */ s.ftype = FT_EXTSEG; @@ -584,8 +568,7 @@ static void ieee_write_fixup(int32_t segment, int32_t wrt, } else /* If we get here the seg value doesn't make sense */ - nasm_panic(0, - "unrecognised segment value in ieee_write_fixup"); + nasm_panic("unrecognised segment value in ieee_write_fixup"); } } else { @@ -639,13 +622,12 @@ static void ieee_write_fixup(int32_t segment, int32_t wrt, } else /* If we get here the seg value doesn't make sense */ - nasm_panic(0, - "unrecognised segment value in ieee_write_fixup"); + nasm_panic("unrecognised segment value in ieee_write_fixup"); } } if (size != 2 && s.ftype == FT_SEG) - nasm_error(ERR_NONFATAL, "IEEE format can only handle 2-byte" - " segment base references"); + nasm_nonfatal("IEEE format can only handle 2-byte" + " segment base references"); s.size = size; ieee_install_fixup(segto, &s); return; @@ -671,7 +653,7 @@ static void ieee_install_fixup(struct ieeeSection *seg, /* * segment registry */ -static int32_t ieee_segment(char *name, int pass, int *bits) +static int32_t ieee_segment(char *name, int *bits) { /* * We call the label manager here to define a name for the new @@ -721,13 +703,15 @@ static int32_t ieee_segment(char *name, int pass, int *bits) for (seg = seghead; seg; seg = seg->next) { ieee_idx++; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass == 1) - nasm_error(ERR_WARNING, "segment attributes specified on" - " redeclaration of segment: ignoring"); + if (attrs > 0 && seg->pass_last_seen == pass_count()) + nasm_warn(WARN_OTHER, "segment attributes specified on" + " redeclaration of segment: ignoring"); if (seg->use32) *bits = 32; else *bits = 16; + + seg->pass_last_seen = pass_count(); return seg->index; } } @@ -778,8 +762,7 @@ static int32_t ieee_segment(char *name, int pass, int *bits) seg->align = 1; if (rn_error) { seg->align = 1; - nasm_error(ERR_NONFATAL, "segment alignment should be" - " numeric"); + nasm_nonfatal("segment alignment should be numeric"); } switch (seg->align) { case 1: /* BYTE */ @@ -793,16 +776,15 @@ static int32_t ieee_segment(char *name, int pass, int *bits) case 128: break; default: - nasm_error(ERR_NONFATAL, "invalid alignment value %d", - seg->align); + nasm_nonfatal("invalid alignment value %d", seg->align); seg->align = 1; break; } } else if (!nasm_strnicmp(p, "absolute=", 9)) { seg->align = SEG_ABS + readnum(p + 9, &rn_error); if (rn_error) - nasm_error(ERR_NONFATAL, "argument to `absolute' segment" - " attribute should be numeric"); + nasm_nonfatal("argument to `absolute' segment" + " attribute should be numeric"); } } @@ -825,11 +807,9 @@ static int32_t ieee_segment(char *name, int pass, int *bits) * directives supported */ static enum directive_result -ieee_directive(enum directive directive, char *value, int pass) +ieee_directive(enum directive directive, char *value) { - (void)value; - (void)pass; switch (directive) { case D_UPPERCASE: @@ -907,7 +887,7 @@ static void ieee_write_file(void) /* * Write the NASM boast comment. */ - ieee_putascii("CO0,%02X%s.\n", strlen(nasm_comment), nasm_comment); + ieee_putascii("CO0,%02X%s.\n", nasm_comment_len(), nasm_comment()); /* * write processor-specific information @@ -979,7 +959,7 @@ static void ieee_write_file(void) if (seg->index == ieee_entry_seg) break; if (!seg) - nasm_panic(0, "Start address records are incorrect"); + nasm_panic("Start address records are incorrect"); else ieee_putascii("ASG,R%X,%lX,+.\n", seg->ieee_index, ieee_entry_ofs); @@ -1293,7 +1273,7 @@ static void dbgls_init(void) arrindex = ARRAY_BOT; arrhead = NULL; arrtail = &arrhead; - ieee_segment("??LINE", 2, &tempint); + ieee_segment("??LINE", &tempint); any_segs = false; } static void dbgls_cleanup(void) @@ -1341,8 +1321,8 @@ static void dbgls_linnum(const char *lnfname, int32_t lineno, int32_t segto) */ if (!any_segs) { int tempint; /* ignored */ - if (segto != ieee_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic(0, "strange segment conditions in OBJ driver"); + if (segto != ieee_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in IEEE driver"); } /* @@ -1352,7 +1332,7 @@ static void dbgls_linnum(const char *lnfname, int32_t lineno, int32_t segto) if (seg->index == segto) break; if (!seg) - nasm_panic(0, "lineno directed to nonexistent segment?"); + nasm_panic("lineno directed to nonexistent segment?"); for (fn = fnhead; fn; fn = fn->next) { if (!nasm_stricmp(lnfname, fn->name)) diff --git a/output/outlib.h b/output/outlib.h index 664ca389..30f2c0b2 100644 --- a/output/outlib.h +++ b/output/outlib.h @@ -41,9 +41,10 @@ uint64_t realsize(enum out_type type, uint64_t size); /* Do-nothing versions of some output routines */ enum directive_result -null_directive(enum directive directive, char *value, int pass); +null_directive(enum directive directive, char *value); void null_sectalign(int32_t seg, unsigned int value); void null_reset(void); +int32_t null_segbase(int32_t seg); /* Do-nothing versions of all the debug routines */ void null_debug_init(void); diff --git a/output/outmacho.c b/output/outmacho.c index e78623e3..8d730bf5 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -38,10 +38,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -56,6 +53,7 @@ #include "outlib.h" #include "ver.h" #include "dwarf.h" +#include "macho.h" #if defined(OF_MACHO) || defined(OF_MACHO64) @@ -72,45 +70,8 @@ #define MACHO_SECTCMD64_SIZE 80 #define MACHO_NLIST64_SIZE 16 -/* Mach-O file header values */ -#define MH_MAGIC 0xfeedface -#define MH_MAGIC_64 0xfeedfacf -#define CPU_TYPE_I386 7 /* x86 platform */ -#define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */ -#define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */ -#define MH_OBJECT 0x1 /* object file */ - -/* Mach-O header flags */ -#define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000 - -/* Mach-O load commands */ -#define LC_SEGMENT 0x1 /* 32-bit segment load cmd */ -#define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */ -#define LC_SYMTAB 0x2 /* symbol table load command */ - /* Mach-O relocations numbers */ -/* Generic relocs, used by i386 Mach-O */ -#define GENERIC_RELOC_VANILLA 0 /* Generic relocation */ -#define GENERIC_RELOC_TLV 5 /* Thread local */ - -#define X86_64_RELOC_UNSIGNED 0 /* Absolute address */ -#define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */ -#define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */ -#define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */ -#define X86_64_RELOC_GOT 4 /* Different GOT entry */ -#define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */ -#define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */ -#define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */ -#define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */ -#define X86_64_RELOC_TLV 9 /* Thread local */ - -/* Mach-O VM permission constants */ -#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) @@ -175,25 +136,6 @@ struct section { uint32_t extreloc; /* external relocations */ }; -#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 */ -#define S_ATTR_DEBUG 0x02000000 -#define S_ATTR_SELF_MODIFYING_CODE 0x04000000 -#define S_ATTR_LIVE_SUPPORT 0x08000000 -#define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ -#define S_ATTR_STRIP_STATIC_SYMS 0x20000000 -#define S_ATTR_NO_TOC 0x40000000 -#define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */ -#define S_ATTR_DEBUG 0x02000000 /* debug section */ - #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */ /* fake section for absolute symbols, *not* part of the section linked list */ @@ -214,10 +156,6 @@ struct reloc { type:4; /* reloc type */ }; -#define R_ABS 0 /* absolute relocation */ -#define R_SCATTERED 0x80000000 /* reloc entry is scattered if - ** highest bit == 1 */ - struct symbol { /* nasm internal data */ struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the @@ -234,23 +172,8 @@ struct symbol { uint16_t desc; /* for stab debugging, 0 for us */ }; -/* symbol type bits */ -#define N_EXT 0x01 /* global or external symbol */ -#define N_PEXT 0x10 /* private 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, **sectstab; static struct symbol *syms, **symstail; static uint32_t nsyms; @@ -313,7 +236,7 @@ static uint64_t rel_padcnt = 0; ALIGN(x, fmt.ptrsize) /* align x to output format width */ static struct hash_table section_by_name; -static struct RAAPTR *section_by_index; +static struct RAA *section_by_index; static struct section * never_null find_or_add_section(const char *segname, const char *sectname) @@ -436,8 +359,7 @@ static void macho_init(void) extsyms = raa_init(); strs = saa_init(1L); - section_by_index = raa_init_ptr(); - hash_init(§ion_by_name, HASH_MEDIUM); + section_by_index = raa_init(); /* string table starts with a zero byte so index 0 is an empty string */ saa_wbytes(strs, zero_buffer, 1); @@ -547,7 +469,7 @@ static int64_t add_reloc(struct section *sect, int32_t section, break; case RL_SUB: /* obsolete */ - nasm_error(ERR_WARNING, "relcation with subtraction" + nasm_error(ERR_WARNING|WARN_OTHER, "relcation with subtraction" "becomes to be obsolete"); r->ext = 0; r->type = X86_64_RELOC_SUBTRACTOR; @@ -632,22 +554,15 @@ static void macho_output(int32_t secto, const void *data, bool is_bss; enum reltype reltype; - if (secto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in " - "[ABSOLUTE] space"); - return; - } - s = get_section_by_index(secto); if (!s) { - nasm_error(ERR_WARNING, "attempt to assemble code in" + nasm_error(ERR_WARNING|WARN_OTHER, "attempt to assemble code in" " section %d: defaulting to `.text'", secto); s = get_section_by_name("__TEXT", "__text"); /* should never happen */ if (!s) - nasm_panic(0, "text section not found"); + nasm_panic("text section not found"); } /* debug code generation only for sections tagged with @@ -663,10 +578,10 @@ static void macho_output(int32_t secto, const void *data, is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL; if (is_bss && type != OUT_RESERVE) { - nasm_error(ERR_WARNING, "attempt to initialize memory in " + nasm_error(ERR_WARNING|WARN_OTHER, "attempt to initialize memory in " "BSS section: ignored"); /* FIXME */ - nasm_error(ERR_WARNING, "section size may be negative" + nasm_error(ERR_WARNING|WARN_OTHER, "section size may be negative" "with address symbols"); s->size += realsize(type, size); return; @@ -677,7 +592,7 @@ static void macho_output(int32_t secto, const void *data, switch (type) { case OUT_RESERVE: if (!is_bss) { - nasm_error(ERR_WARNING, "uninitialized space declared in" + nasm_error(ERR_WARNING|WARN_OTHER, "uninitialized space declared in" " %s,%s section: zeroing", s->segname, s->sectname); sect_write(s, NULL, size); @@ -687,9 +602,6 @@ static void macho_output(int32_t secto, const void *data, break; case OUT_RAWDATA: - if (section != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); - sect_write(s, data, size); break; @@ -818,59 +730,74 @@ static void macho_output(int32_t secto, const void *data, } } +#define S_CODE (S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS) +#define NO_TYPE S_NASM_TYPE_MASK + /* Translation table from traditional Unix section names to Mach-O */ -static const struct sectmap { - const char *nasmsect; - const char *segname; - const char *sectname; - const uint32_t flags; -} sectmap[] = { - {".text", "__TEXT", "__text", - S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS}, - {".data", "__DATA", "__data", S_REGULAR}, - {".rodata", "__DATA", "__const", S_REGULAR}, - {".bss", "__DATA", "__bss", S_ZEROFILL}, - {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG}, - {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG}, - {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG}, - {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG}, - {NULL, NULL, NULL, 0} +static const struct macho_known_section { + const char *nasmsect; + const char *segname; + const char *sectname; + const uint32_t flags; +} known_sections[] = { + { ".text", "__TEXT", "__text", S_CODE }, + { ".data", "__DATA", "__data", S_REGULAR }, + { ".rodata", "__DATA", "__const", S_REGULAR }, + { ".bss", "__DATA", "__bss", S_ZEROFILL }, + { ".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG }, + { ".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG }, + { ".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG }, + { ".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG }, }; -#define NO_TYPE S_NASM_TYPE_MASK - /* Section type or attribute directives */ -static const struct sect_attribs { - const char *name; - uint32_t flags; +static const struct macho_known_section_attr { + const char *name; + uint32_t flags; } sect_attribs[] = { - { "data", S_REGULAR }, - { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS }, - { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS }, - { "bss", S_ZEROFILL }, - { "zerofill", S_ZEROFILL }, - { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP }, - { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT }, - { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS }, - { "debug", NO_TYPE|S_ATTR_DEBUG }, + { "data", S_REGULAR }, + { "code", S_CODE }, + { "mixed", S_REGULAR | S_ATTR_SOME_INSTRUCTIONS }, + { "bss", S_ZEROFILL }, + { "zerofill", S_ZEROFILL }, + { "no_dead_strip", NO_TYPE | S_ATTR_NO_DEAD_STRIP }, + { "live_support", NO_TYPE | S_ATTR_LIVE_SUPPORT }, + { "strip_static_syms", NO_TYPE | S_ATTR_STRIP_STATIC_SYMS }, + { "debug", NO_TYPE | S_ATTR_DEBUG }, { NULL, 0 } }; -static int32_t macho_section(char *name, int pass, int *bits) +static const struct macho_known_section * +lookup_known_section(const char *name, bool by_sectname) { + size_t i; + + if (name && name[0]) { + for (i = 0; i < ARRAY_SIZE(known_sections); i++) { + const char *p = by_sectname ? + known_sections[i].sectname : + known_sections[i].nasmsect; + if (!strcmp(name, p)) + return &known_sections[i]; + } + } + + return NULL; +} + +static int32_t macho_section(char *name, int *bits) +{ + const struct macho_known_section *known_section; + const struct macho_known_section_attr *sa; char *sectionAttributes; - const struct sectmap *sm; struct section *s; const char *section, *segment; uint32_t flags; - const struct sect_attribs *sa; char *currentAttribute; char *comma; bool new_seg; - (void)pass; - /* Default to the appropriate number of bits. */ if (!name) { *bits = fmt.ptrsize << 3; @@ -906,29 +833,23 @@ static int32_t macho_section(char *name, int pass, int *bits) nasm_error(ERR_NONFATAL, "section name %s too long\n", section); } - if (!strcmp(section, "__text")) { - flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | - S_ATTR_PURE_INSTRUCTIONS; - } else if (!strcmp(section, "__bss")) { - flags = S_ZEROFILL; - } else { - flags = S_REGULAR; - } + known_section = lookup_known_section(section, true); + if (known_section) + flags = known_section->flags; + else + flags = S_REGULAR; } else { - for (sm = sectmap; sm->nasmsect != NULL; ++sm) { - /* make lookup into section name translation table */ - if (!strcmp(name, sm->nasmsect)) { - segment = sm->segname; - section = sm->sectname; - flags = sm->flags; - goto found; - } - } - nasm_error(ERR_NONFATAL, "unknown section name\n"); - return NO_SEG; + known_section = lookup_known_section(name, false); + if (!known_section) { + nasm_error(ERR_NONFATAL, "unknown section name %s\n", name); + return NO_SEG; + } + + segment = known_section->segname; + section = known_section->sectname; + flags = known_section->flags; } - found: /* try to find section with that name, or create it */ s = find_or_add_section(segment, section); new_seg = is_new_section(s); @@ -1060,8 +981,9 @@ static void macho_symdef(char *name, int32_t section, int64_t offset, #if defined(DEBUG) && DEBUG>2 nasm_error(ERR_DEBUG, - " macho_symdef: %s, pass0=%d, passn=%"PRId64", sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", - name, pass0, passn, section, offset, is_global, special); + " macho_symdef: %s, pass=%"PRId64" type %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", + name, pass_count(), pass_types[pass_type()], + section, offset, is_global, special); #endif if (is_global == 3) { @@ -1161,7 +1083,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset, /* 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) */ - nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global); + nasm_panic("in-file index for section %d not found, is_global = %d", section, is_global); break; } } @@ -1196,11 +1118,6 @@ static void macho_sectalign(int32_t seg, unsigned int value) s->align = align; } -static int32_t macho_segbase(int32_t section) -{ - return section; -} - extern macros_t macho_stdmac[]; /* Comparison function for qsort symbol layout. */ @@ -1359,7 +1276,7 @@ static void macho_calculate_sizes (void) } if (seg_nsects > MAX_SECT) { - nasm_fatal(0, "MachO output is limited to %d sections\n", + nasm_fatal("MachO output is limited to %d sections\n", MAX_SECT); } @@ -1734,7 +1651,7 @@ static void macho_write (void) if (seg_nsects > 0) offset = macho_write_segment (offset); else - nasm_error(ERR_WARNING, "no sections?"); + nasm_error(ERR_WARNING|WARN_OTHER, "no sections?"); if (nsyms > 0) { /* write out symbol command */ @@ -1813,7 +1730,7 @@ static void macho_cleanup(void) nasm_free(extdefsyms); nasm_free(undefsyms); nasm_free(sectstab); - raa_free_ptr(section_by_index); + raa_free(section_by_index); hash_free(§ion_by_name); } @@ -1846,7 +1763,6 @@ static enum directive_result macho_no_dead_strip(const char *labels) char *s, *p, *ep; char ec; enum directive_result rv = DIRR_ERROR; - bool real = passn > 1; p = s = nasm_strdup(labels); while (*p) { @@ -1861,7 +1777,7 @@ static enum directive_result macho_no_dead_strip(const char *labels) goto err; } *ep = '\0'; - if (real) { + if (!pass_first()) { if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP)) rv = DIRR_ERROR; } @@ -1884,14 +1800,12 @@ err: static enum directive_result macho_pragma(const struct pragma *pragma) { - bool real = passn > 1; - switch (pragma->opcode) { case D_SUBSECTIONS_VIA_SYMBOLS: if (*pragma->tail) return DIRR_BADPARAM; - if (real) + if (!pass_first()) head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS; /* Jmp-match optimization conflicts */ @@ -1923,10 +1837,10 @@ static void macho_dbg_generate(void) /* debug section defines */ { int bits = 0; - macho_section(".debug_abbrev", 0, &bits); - macho_section(".debug_info", 0, &bits); - macho_section(".debug_line", 0, &bits); - macho_section(".debug_str", 0, &bits); + macho_section(".debug_abbrev", &bits); + macho_section(".debug_info", &bits); + macho_section(".debug_line", &bits); + macho_section(".debug_str", &bits); } /* dw section walk to find high_addr and total_len */ @@ -2028,7 +1942,7 @@ static void macho_dbg_generate(void) nasm_assert(p_section != NULL); producer_str_offset = 0; - module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature); + module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature()); dir_str_offset += saa_wcstring(p_str, cur_file); saa_wcstring(p_str, cur_dir); @@ -2402,7 +2316,7 @@ const struct ofmt of_macho32 = { macho_section, macho_herelabel, macho_sectalign, - macho_segbase, + null_segbase, null_directive, macho_cleanup, macho_pragma_list @@ -2469,7 +2383,7 @@ const struct ofmt of_macho64 = { macho_section, macho_herelabel, macho_sectalign, - macho_segbase, + null_segbase, null_directive, macho_cleanup, macho_pragma_list, diff --git a/output/outobj.c b/output/outobj.c index b4f2c499..a5936279 100644 --- a/output/outobj.c +++ b/output/outobj.c @@ -38,11 +38,8 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <limits.h> +#include <ctype.h> /* For toupper() */ +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -580,6 +577,7 @@ static struct Segment { struct Group *grp; /* the group it beint32_ts to */ uint32_t currentpos; int32_t align; /* can be SEG_ABS + absolute addr */ + int64_t pass_last_seen; struct Public *pubhead, **pubtail, *lochead, **loctail; char *segclass, *overlay; /* `class' is a C++ keyword :-) */ ObjRecord *orp; @@ -634,9 +632,9 @@ static const struct dfmt borland_debug_form; /* The current segment */ static struct Segment *current_seg; -static int32_t obj_segment(char *, int, int *); +static int32_t obj_segment(char *, int *); static void obj_write_file(void); -static enum directive_result obj_directive(enum directive, char *, int); +static enum directive_result obj_directive(enum directive, char *); static void obj_init(void) { @@ -774,8 +772,7 @@ static void obj_deflabel(char *name, int32_t segment, bool used_special = false; /* have we used the special text? */ #if defined(DEBUG) && DEBUG>2 - nasm_error(ERR_DEBUG, - " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", + nasm_debug(" obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", name, segment, offset, is_global, special); #endif @@ -795,7 +792,7 @@ static void obj_deflabel(char *name, int32_t segment, obj_entry_ofs = offset; return; } - nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name); + nasm_nonfatal("unrecognised special symbol `%s'", name); } /* @@ -826,8 +823,8 @@ static void obj_deflabel(char *name, int32_t segment, pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS); } if (special) - nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features" - " for this symbol type"); + nasm_nonfatal("OBJ supports no special symbol features" + " for this symbol type"); return; } @@ -838,8 +835,8 @@ static void obj_deflabel(char *name, int32_t segment, */ if (!any_segs && segment == first_seg) { int tempint; /* ignored */ - if (segment != obj_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic(0, "strange segment conditions in OBJ driver"); + if (segment != obj_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in OBJ driver"); } for (seg = seghead; seg && is_global; seg = seg->next) @@ -855,9 +852,8 @@ static void obj_deflabel(char *name, int32_t segment, loc->offset = offset; if (special) - nasm_error(ERR_NONFATAL, - "OBJ supports no special symbol features" - " for this symbol type"); + nasm_nonfatal("OBJ supports no special symbol features" + " for this symbol type"); return; } @@ -922,8 +918,8 @@ static void obj_deflabel(char *name, int32_t segment, obj_ext_set_defwrt(ext, p); special += len; if (*special && *special != ':') - nasm_error(ERR_NONFATAL, "`:' expected in special symbol" - " text for `%s'", ext->name); + nasm_nonfatal("`:' expected in special symbol" + " text for `%s'", ext->name); else if (*special == ':') special++; } @@ -936,18 +932,16 @@ static void obj_deflabel(char *name, int32_t segment, if (ext->commonsize) ext->commonelem = 1; else - nasm_error(ERR_NONFATAL, - "`%s': `far' keyword may only be applied" - " to common variables\n", ext->name); + nasm_nonfatal("`%s': `far' keyword may only be applied" + " to common variables\n", ext->name); special += 3; special += strspn(special, " \t"); } else if (!nasm_strnicmp(special, "near", 4)) { if (ext->commonsize) ext->commonelem = 0; else - nasm_error(ERR_NONFATAL, - "`%s': `far' keyword may only be applied" - " to common variables\n", ext->name); + nasm_nonfatal("`%s': `far' keyword may only be applied" + " to common variables\n", ext->name); special += 4; special += strspn(special, " \t"); } @@ -971,16 +965,15 @@ static void obj_deflabel(char *name, int32_t segment, e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL); if (e) { if (!is_simple(e)) - nasm_error(ERR_NONFATAL, "cannot use relocatable" - " expression as common-variable element size"); + nasm_nonfatal("cannot use relocatable" + " expression as common-variable element size"); else ext->commonelem = reloc_value(e); } special = stdscan_get(); } else { - nasm_error(ERR_NONFATAL, - "`%s': element-size specifications only" - " apply to common variables", ext->name); + nasm_nonfatal("`%s': element-size specifications only" + " apply to common variables", ext->name); while (*special && *special != ':') special++; if (*special == ':') @@ -1010,8 +1003,8 @@ static void obj_deflabel(char *name, int32_t segment, ext->index = ++externals; if (special && !used_special) - nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features" - " for this symbol type"); + nasm_nonfatal("OBJ supports no special symbol features" + " for this symbol type"); } /* forward declaration */ @@ -1029,23 +1022,13 @@ static void obj_out(int32_t segto, const void *data, ObjRecord *orp; /* - * handle absolute-assembly (structure definitions) - */ - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]" - " space"); - return; - } - - /* * If `any_segs' is still false, we must define a default * segment. */ if (!any_segs) { int tempint; /* ignored */ - if (segto != obj_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic(0, "strange segment conditions in OBJ driver"); + if (segto != obj_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in OBJ driver"); } /* @@ -1055,7 +1038,7 @@ static void obj_out(int32_t segto, const void *data, if (seg->index == segto) break; if (!seg) - nasm_panic(0, "code directed to nonexistent segment?"); + nasm_panic("code directed to nonexistent segment?"); orp = seg->orp; orp->parm[0] = seg->currentpos; @@ -1089,11 +1072,11 @@ static void obj_out(int32_t segto, const void *data, size = abs((int)size); if (segment == NO_SEG && type != OUT_ADDRESS) - nasm_error(ERR_NONFATAL, "relative call to absolute address not" - " supported by OBJ format"); + nasm_nonfatal("relative call to absolute address not" + " supported by OBJ format"); if (segment >= SEG_ABS) - nasm_error(ERR_NONFATAL, "far-absolute relocations not supported" - " by OBJ format"); + nasm_nonfatal("far-absolute relocations not supported" + " by OBJ format"); ldata = *(int64_t *)data; if (type != OUT_ADDRESS) { @@ -1138,8 +1121,8 @@ static void obj_out(int32_t segto, const void *data, switch (size) { default: - nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or " - "32-byte relocations"); + nasm_nonfatal("OBJ format can only handle 16- or " + "32-byte relocations"); segment = NO_SEG; /* Don't actually generate a relocation */ break; case 2: @@ -1162,8 +1145,8 @@ static void obj_out(int32_t segto, const void *data, */ rsize = 2; if (ldata & 0xFFFF) - nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex" - " dword-size segment base references"); + nasm_nonfatal("OBJ format cannot handle complex" + " dword-size segment base references"); } if (segment != NO_SEG) obj_write_fixup(orp, rsize, @@ -1174,8 +1157,7 @@ static void obj_out(int32_t segto, const void *data, } default: - nasm_error(ERR_NONFATAL, - "Relocation type not supported by output format"); + nasm_nonfatal("Relocation type not supported by output format"); /* fall through */ case OUT_RESERVE: @@ -1201,8 +1183,8 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, ObjRecord *forp; if (bytes != 2 && bytes != 4) { - nasm_error(ERR_NONFATAL, "`obj' output driver does not support" - " %d-bit relocations", bytes << 3); + nasm_nonfatal("`obj' output driver does not support" + " %d-bit relocations", bytes << 3); return; } @@ -1223,7 +1205,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, locat = FIX_16_SELECTOR; seg--; if (bytes != 2) - nasm_panic(0, "OBJ: 4-byte segment base fixup got" + nasm_panic("OBJ: 4-byte segment base fixup got" " through sanity check"); } else { base = false; @@ -1269,8 +1251,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, if (eb) method = 6, e = eb->exts[i], tidx = e->index; else - nasm_panic(0, - "unrecognised segment value in obj_write_fixup"); + nasm_panic("unrecognised segment value in obj_write_fixup"); } } @@ -1293,8 +1274,8 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, else if (e->defwrt_type == DEFWRT_GROUP) method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index; else { - nasm_error(ERR_NONFATAL, "default WRT specification for" - " external `%s' unresolved", e->name); + nasm_nonfatal("default WRT specification for" + " external `%s' unresolved", e->name); method |= 0x50, fidx = -1; /* got to do _something_ */ } } else @@ -1328,8 +1309,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, if (eb) method |= 0x20, fidx = eb->exts[i]->index; else - nasm_panic(0, - "unrecognised WRT value in obj_write_fixup"); + nasm_panic("unrecognised WRT value in obj_write_fixup"); } } } @@ -1341,7 +1321,7 @@ static void obj_write_fixup(ObjRecord * orp, int bytes, obj_commit(forp); } -static int32_t obj_segment(char *name, int pass, int *bits) +static int32_t obj_segment(char *name, int *bits) { /* * We call the label manager here to define a name for the new @@ -1351,8 +1331,8 @@ static int32_t obj_segment(char *name, int pass, int *bits) * by sponging off the label manager. */ #if defined(DEBUG) && DEBUG>=3 - nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n", - name, pass, *bits); + nasm_debug(" obj_segment: < %s >, pass=%d, *bits=%d\n", + name, pass, *bits); #endif if (!name) { *bits = 16; @@ -1397,14 +1377,15 @@ static int32_t obj_segment(char *name, int pass, int *bits) break; if (!strcmp(seg->name, name)) { - if (attrs > 0 && pass == 1) - nasm_error(ERR_WARNING, "segment attributes specified on" - " redeclaration of segment: ignoring"); + if (attrs > 0 && seg->pass_last_seen == pass_count()) + nasm_warn(WARN_OTHER, "segment attributes specified on" + " redeclaration of segment: ignoring"); if (seg->use32) *bits = 32; else *bits = 16; current_seg = seg; + seg->pass_last_seen = pass_count(); return seg->index; } } @@ -1473,12 +1454,12 @@ static int32_t obj_segment(char *name, int pass, int *bits) if (!strcmp(grp->name, "FLAT")) break; if (!grp) { - obj_directive(D_GROUP, "FLAT", 1); + obj_directive(D_GROUP, "FLAT"); for (grp = grphead; grp; grp = grp->next) if (!strcmp(grp->name, "FLAT")) break; if (!grp) - nasm_panic(0, "failure to define FLAT?!"); + nasm_panic("failure to define FLAT?!"); } seg->grp = grp; } else if (!nasm_strnicmp(p, "class=", 6)) @@ -1489,8 +1470,7 @@ static int32_t obj_segment(char *name, int pass, int *bits) seg->align = readnum(p + 6, &rn_error); if (rn_error) { seg->align = 1; - nasm_error(ERR_NONFATAL, "segment alignment should be" - " numeric"); + nasm_nonfatal("segment alignment should be numeric"); } switch (seg->align) { case 1: /* BYTE */ @@ -1501,38 +1481,35 @@ static int32_t obj_segment(char *name, int pass, int *bits) case 4096: /* PharLap extension */ break; case 8: - nasm_error(ERR_WARNING, - "OBJ format does not support alignment" - " of 8: rounding up to 16"); + nasm_warn(WARN_OTHER, "OBJ format does not support alignment" + " of 8: rounding up to 16"); seg->align = 16; break; case 32: case 64: case 128: - nasm_error(ERR_WARNING, - "OBJ format does not support alignment" - " of %d: rounding up to 256", seg->align); + nasm_warn(WARN_OTHER, "OBJ format does not support alignment" + " of %d: rounding up to 256", seg->align); seg->align = 256; break; case 512: case 1024: case 2048: - nasm_error(ERR_WARNING, - "OBJ format does not support alignment" - " of %d: rounding up to 4096", seg->align); + nasm_warn(WARN_OTHER, "OBJ format does not support alignment" + " of %d: rounding up to 4096", seg->align); seg->align = 4096; break; default: - nasm_error(ERR_NONFATAL, "invalid alignment value %d", - seg->align); + nasm_nonfatal("invalid alignment value %d", + seg->align); seg->align = 1; break; } } else if (!nasm_strnicmp(p, "absolute=", 9)) { seg->align = SEG_ABS + readnum(p + 9, &rn_error); if (rn_error) - nasm_error(ERR_NONFATAL, "argument to `absolute' segment" - " attribute should be numeric"); + nasm_nonfatal("argument to `absolute' segment" + " attribute should be numeric"); } } @@ -1556,10 +1533,9 @@ static int32_t obj_segment(char *name, int pass, int *bits) grp->segs[i] = grp->segs[grp->nindices]; grp->segs[grp->nindices++].index = seg->obj_index; if (seg->grp) - nasm_error(ERR_WARNING, - "segment `%s' is already part of" - " a group: first one takes precedence", - seg->name); + nasm_warn(WARN_OTHER, "segment `%s' is already part of" + " a group: first one takes precedence", + seg->name); else seg->grp = grp; } @@ -1593,13 +1569,13 @@ static int32_t obj_segment(char *name, int pass, int *bits) } static enum directive_result -obj_directive(enum directive directive, char *value, int pass) +obj_directive(enum directive directive, char *value) { switch (directive) { case D_GROUP: { char *p, *q, *v; - if (pass == 1) { + if (pass_first()) { /* XXX */ struct Group *grp; struct Segment *seg; struct External **extp; @@ -1632,7 +1608,7 @@ obj_directive(enum directive directive, char *value, int pass) for (grp = grphead; grp; grp = grp->next) { obj_idx++; if (!strcmp(grp->name, v)) { - nasm_error(ERR_NONFATAL, "group `%s' defined twice", v); + nasm_nonfatal("group `%s' defined twice", v); return DIRR_ERROR; } } @@ -1672,10 +1648,9 @@ obj_directive(enum directive directive, char *value, int pass) grp->segs[grp->nentries++] = grp->segs[grp->nindices]; grp->segs[grp->nindices++].index = seg->obj_index; if (seg->grp) - nasm_error(ERR_WARNING, - "segment `%s' is already part of" - " a group: first one takes precedence", - seg->name); + nasm_warn(WARN_OTHER, "segment `%s' is already part of" + " a group: first one takes precedence", + seg->name); else seg->grp = grp; } else { @@ -1714,8 +1689,8 @@ obj_directive(enum directive directive, char *value, int pass) { char *q, *extname, *libname, *impname; - if (pass == 2) - return 1; /* ignore in pass two */ + if (!pass_first()) /* XXX */ + return DIRR_OK; extname = q = value; while (*q && !nasm_isspace(*q)) q++; @@ -1737,8 +1712,8 @@ obj_directive(enum directive directive, char *value, int pass) impname = q; if (!*extname || !*libname) - nasm_error(ERR_NONFATAL, "`import' directive requires symbol name" - " and library name"); + nasm_nonfatal("`import' directive requires symbol name" + " and library name"); else { struct ImpDef *imp; bool err = false; @@ -1764,7 +1739,7 @@ obj_directive(enum directive directive, char *value, int pass) int flags = 0; unsigned int ordinal = 0; - if (pass == 2) + if (!pass_first()) return DIRR_OK; /* ignore in pass two */ intname = q = value; while (*q && !nasm_isspace(*q)) @@ -1785,7 +1760,7 @@ obj_directive(enum directive directive, char *value, int pass) } if (!*intname) { - nasm_error(ERR_NONFATAL, "`export' directive requires export name"); + nasm_nonfatal("`export' directive requires export name"); return DIRR_OK; } if (!*extname) { @@ -1809,16 +1784,14 @@ obj_directive(enum directive directive, char *value, int pass) bool err = false; flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err); if (err) { - nasm_error(ERR_NONFATAL, - "value `%s' for `parm' is non-numeric", v + 5); + nasm_nonfatal("value `%s' for `parm' is non-numeric", v + 5); return DIRR_ERROR; } } else { bool err = false; ordinal = readnum(v, &err); if (err) { - nasm_error(ERR_NONFATAL, - "unrecognised export qualifier `%s'", v); + nasm_nonfatal("unrecognised export qualifier `%s'", v); return DIRR_ERROR; } flags |= EXPDEF_FLAG_ORDINAL; @@ -1913,7 +1886,7 @@ static int32_t obj_segbase(int32_t segment) e = eb->exts[i]; if (!e) { /* Not available yet, probably a forward reference */ - nasm_assert(pass0 < 2); /* Convergence failure */ + nasm_assert(!pass_final()); return NO_SEG; } @@ -1977,7 +1950,7 @@ static void obj_write_file(void) struct ExpDef *export; int lname_idx; ObjRecord *orp; - const StrList *depfile; + const struct strlist_entry *depfile; const bool debuginfo = (dfmt == &borland_debug_form); /* @@ -1993,14 +1966,14 @@ static void obj_write_file(void) */ orp->type = COMENT; obj_rword(orp, dTRANSL); - obj_name(orp, nasm_comment); + obj_name(orp, nasm_comment()); obj_emit2(orp); /* * Output file dependency information */ - if (!obj_nodepend) { - list_for_each(depfile, depend_list) { + if (!obj_nodepend && depend_list) { + strlist_for_each(depfile, depend_list) { uint32_t ts; ts = obj_file_timestamp(depfile->str); @@ -2104,8 +2077,8 @@ static void obj_write_file(void) /* acbp |= 0x00 */ ; else if (seg->align >= 4096) { if (seg->align > 4096) - nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment" - " than OBJ format supports", seg->name); + nasm_nonfatal("segment `%s' requires more alignment" + " than OBJ format supports", seg->name); acbp |= 0xC0; /* PharLap extension */ } else if (seg->align >= 256) { acbp |= 0x80; @@ -2139,8 +2112,8 @@ static void obj_write_file(void) if (grp->nindices != grp->nentries) { for (i = grp->nindices; i < grp->nentries; i++) { - nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment" - " `%s'", grp->name, grp->segs[i].name); + nasm_nonfatal("group `%s' contains undefined segment" + " `%s'", grp->name, grp->segs[i].name); nasm_free(grp->segs[i].name); grp->segs[i].name = NULL; } @@ -2362,7 +2335,7 @@ static void obj_write_file(void) } } if (!seg) - nasm_error(ERR_NONFATAL, "entry point is not in this module"); + nasm_nonfatal("entry point is not in this module"); } /* @@ -2528,8 +2501,8 @@ static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto) */ if (!any_segs) { int tempint; /* ignored */ - if (segto != obj_segment("__NASMDEFSEG", 2, &tempint)) - nasm_panic(0, "strange segment conditions in OBJ driver"); + if (segto != obj_segment("__NASMDEFSEG", &tempint)) + nasm_panic("strange segment conditions in OBJ driver"); } /* @@ -2539,7 +2512,7 @@ static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto) if (seg->index == segto) break; if (!seg) - nasm_panic(0, "lineno directed to nonexistent segment?"); + nasm_panic("lineno directed to nonexistent segment?"); /* for (fn = fnhead; fn; fn = fnhead->next) */ for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */ diff --git a/output/outrdf2.c b/output/outrdf2.c index 9af827cb..d020d91e 100644 --- a/output/outrdf2.c +++ b/output/outrdf2.c @@ -39,11 +39,7 @@ #include "compiler.h" -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <assert.h> +#include "nctype.h" #include "nasm.h" #include "nasmlib.h" @@ -145,14 +141,13 @@ static void rdf2_init(void) segdata = seg_alloc(); segbss = seg_alloc(); if (segtext != 0 || segdata != 2 || segbss != 4) - nasm_panic(0, - "rdf segment numbers not allocated as expected (%d,%d,%d)", - segtext, segdata, segbss); + nasm_panic("rdf segment numbers not allocated as expected (%d,%d,%d)", + segtext, segdata, segbss); bsslength = 0; headerlength = 0; } -static int32_t rdf2_section_names(char *name, int pass, int *bits) +static int32_t rdf2_section_names(char *name, int *bits) { int i; bool err; @@ -160,8 +155,6 @@ static int32_t rdf2_section_names(char *name, int pass, int *bits) int code = -1; int reserved = 0; - (void)pass; - /* * Default is 32 bits, in the text segment. */ @@ -227,7 +220,7 @@ static int32_t rdf2_section_names(char *name, int pass, int *bits) code = 3; } if (nsegments == RDF_MAXSEGS) { - nasm_fatal(0, "reached compiled-in maximum segment limit (%d)", + nasm_fatal("reached compiled-in maximum segment limit (%d)", RDF_MAXSEGS); return NO_SEG; } @@ -235,7 +228,7 @@ static int32_t rdf2_section_names(char *name, int pass, int *bits) segments[nsegments].segname = nasm_strdup(name); i = seg_alloc(); if (i % 2 != 0) - nasm_panic(0, "seg_alloc() returned odd number"); + nasm_panic("seg_alloc() returned odd number"); segments[nsegments].segnumber = i >> 1; segments[nsegments].segtype = code; segments[nsegments].segreserved = reserved; @@ -497,7 +490,7 @@ static void membufwrite(int segment, const void *data, int bytes) break; } if (i == nsegments) - nasm_panic(0, "can't find segment %d", segment); + nasm_panic("can't find segment %d", segment); if (bytes < 0) { b = buf; @@ -520,7 +513,7 @@ static int getsegmentlength(int segment) break; } if (i == nsegments) - nasm_panic(0, "can't find segment %d", segment); + nasm_panic("can't find segment %d", segment); return segments[i].seglength; } @@ -533,13 +526,6 @@ static void rdf2_out(int32_t segto, const void *data, uint8_t databuf[8], *pd; int seg; - if (segto == NO_SEG) { - if (type != OUT_RESERVE) - nasm_error(ERR_NONFATAL, - "attempt to assemble code in ABSOLUTE space"); - return; - } - segto >>= 1; /* convert NASM segment no to RDF number */ for (seg = 0; seg < nsegments; seg++) { @@ -576,9 +562,6 @@ static void rdf2_out(int32_t segto, const void *data, while (size--) membufwrite(segto, databuf, 1); } else if (type == OUT_RAWDATA) { - if (segment != NO_SEG) - nasm_panic(0, "OUT_RAWDATA with other than NO_SEG"); - membufwrite(segto, data, size); } else if (type == OUT_ADDRESS) { int asize = abs((int)size); @@ -606,7 +589,7 @@ static void rdf2_out(int32_t segto, const void *data, membufwrite(segto, databuf, asize); } else if (type == OUT_REL2ADR) { if (segment == segto) - nasm_panic(0, "intra-segment OUT_REL2ADR"); + nasm_panic("intra-segment OUT_REL2ADR"); rr.reclen = 8; rr.offset = getsegmentlength(segto); /* current offset */ @@ -638,9 +621,9 @@ static void rdf2_out(int32_t segto, const void *data, membufwrite(segto, &rr.offset, -2); } else if (type == OUT_REL4ADR) { if ((segment == segto) && (globalbits != 64)) - nasm_panic(0, "intra-segment OUT_REL4ADR"); + nasm_panic("intra-segment OUT_REL4ADR"); if (segment != NO_SEG && segment % 2) { - nasm_panic(0, "erm... 4 byte segment base ref?"); + nasm_panic("erm... 4 byte segment base ref?"); } rr.type = RDFREC_RELOC; /* type signature */ @@ -712,16 +695,11 @@ static void rdf2_cleanup(void) fwriteint16_t(0, ofile); } -static int32_t rdf2_segbase(int32_t segment) -{ - return segment; -} - /* * Handle RDOFF2 specific directives */ static enum directive_result -rdf2_directive(enum directive directive, char *value, int pass) +rdf2_directive(enum directive directive, char *value) { size_t n; @@ -732,7 +710,7 @@ rdf2_directive(enum directive directive, char *value, int pass) nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); return DIRR_ERROR; } - if (pass == 1) { + if (pass_first()) { /* XXX */ struct DLLRec r; r.type = RDFREC_DLL; r.reclen = n + 1; @@ -746,7 +724,7 @@ rdf2_directive(enum directive directive, char *value, int pass) nasm_error(ERR_NONFATAL, "name size exceeds %d bytes", MODLIB_NAME_MAX); return DIRR_ERROR; } - if (pass == 1) { + if (pass_first()) { /* XXX */ struct ModRec r; r.type = RDFREC_MODNAME; r.reclen = n + 1; @@ -779,7 +757,7 @@ const struct ofmt of_rdf2 = { rdf2_section_names, NULL, null_sectalign, - rdf2_segbase, + null_segbase, rdf2_directive, rdf2_cleanup, NULL /* pragma list */ diff --git a/output/pecoff.h b/output/pecoff.h index 8b57d6b2..7b6f46c2 100644 --- a/output/pecoff.h +++ b/output/pecoff.h @@ -484,6 +484,7 @@ struct coff_Section { char *name; int32_t namepos; /* Offset of name into the strings table */ int32_t pos, relpos; + int64_t pass_last_seen; }; struct coff_Reloc { diff --git a/output/stabs.h b/output/stabs.h index 57f15cf2..dbc49868 100644 --- a/output/stabs.h +++ b/output/stabs.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2010 The NASM Authors - All Rights Reserved + * Copyright 1996-2018 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -34,7 +34,7 @@ #ifndef STABS_H_ #define STABS_H_ -#include <ctype.h> +#include "nctype.h" #include "compiler.h" #include "nasmlib.h" @@ -42,103 +42,109 @@ /* offsets */ enum stab_offsets { - STAB_strdxoff = 0, - STAB_typeoff = 4, - STAB_otheroff = 5, - STAB_descoff = 6, - STAB_valoff = 8, - STAB_stabsize = 12 + STAB_strdxoff = 0, + STAB_typeoff = 4, + STAB_otheroff = 5, + STAB_descoff = 6, + STAB_valoff = 8, + STAB_stabsize = 12 }; /* stab/non-stab types */ enum stab_types { - N_UNDF = 0x00, - N_ABS = 0x02, - N_ABS_EXT = 0x03, - N_TEXT = 0x04, - N_TEXT_EXT = 0x05, - N_DATA = 0x06, - N_DATA_EXT = 0x07, - N_BSS = 0x08, - N_BSS_EXT = 0x09, - N_FN_SEQ = 0x0c, - N_INDR = 0x0a, - N_COMM = 0x12, - N_SETA = 0x14, - N_SETA_EXT = 0x15, - N_SETT = 0x16, - N_SETT_EXT = 0x17, - N_SETD = 0x18, - N_SETD_EXT = 0x19, - N_SETB = 0x1a, - N_SETB_EXT = 0x1b, - N_SETV = 0x1c, - N_SETV_EXT = 0x1d, - N_WARNING = 0x1e, - N_FN = 0x1f, - N_GSYM = 0x20, - N_FNAME = 0x22, - N_FUN = 0x24, - N_STSYM = 0x26, - N_LCSYM = 0x28, - N_MAIN = 0x2a, - N_ROSYM = 0x2c, - N_BNSYM = 0x2e, - N_PC = 0x30, - N_NSYMS = 0x32, - N_NOMAP = 0x34, - N_OBJ = 0x38, - N_OPT = 0x3c, - N_RSYM = 0x40, - N_M2C = 0x42, - N_SLINE = 0x44, - N_DSLINE = 0x46, - N_BSLINE = 0x48, - N_BROWS = 0x48, - N_DEFD = 0x4a, - N_FLINE = 0x4c, - N_ENSYM = 0x4e, - N_EHDECL = 0x50, - N_MOD2 = 0x50, - N_CATCH = 0x54, - N_SSYM = 0x60, - N_ENDM = 0x62, - N_SO = 0x64, /* ID for main source file */ - N_OSO = 0x66, - N_ALIAS = 0x6c, - N_LSYM = 0x80, - N_BINCL = 0x82, - N_SOL = 0x84, /* ID for sub-source file */ - N_PSYM = 0xa0, - N_EINCL = 0xa2, - N_ENTRY = 0xa4, - N_LBRAC = 0xc0, - N_EXCL = 0xc2, - N_SCOPE = 0xc4, - N_PATCH = 0xd0, - N_RBRAC = 0xe0, - N_BCOMM = 0xe2, - N_ECOMM = 0xe4, - N_ECOML = 0xe8, - N_WITH = 0xea, - N_NBTEXT = 0xf0, - N_NBDATA = 0xf2, - N_NBBSS = 0xf4, - N_NBSTS = 0xf6, - N_NBLCS = 0xf8, - N_LENG = 0xfe + N_UNDF = 0x00, /* Undefined symbol */ + N_EXT = 0x01, /* External symbol */ + N_ABS = 0x02, /* Absolute symbol */ + N_ABS_EXT = 0x03, /* Absolute external symbol */ + N_TEXT = 0x04, /* Symbol in text segment */ + N_TEXT_EXT = 0x05, /* Symbol in external text segment */ + N_DATA = 0x06, + N_DATA_EXT = 0x07, + N_BSS = 0x08, + N_BSS_EXT = 0x09, + N_INDR = 0x0a, + N_FN_SEQ = 0x0c, /* N_FN from Sequent compilers */ + N_WEAKU = 0x0d, /* Weak undefined symbol */ + N_WEAKA = 0x0e, /* Weak absolute symbl */ + N_WEAKT = 0x0f, /* Weak text symbol */ + N_WEAKD = 0x10, /* Weak data symbol */ + N_WEAKB = 0x11, /* Weak bss symbol */ + N_COMM = 0x12, /* Common symbol */ + N_SETA = 0x14, /* Absolute set element symbol */ + N_SETA_EXT = 0x15, + N_SETT = 0x16, /* Text set element symbol */ + N_SETT_EXT = 0x17, + N_SETD = 0x18, /* Data set element symbol */ + N_SETD_EXT = 0x19, + N_SETB = 0x1a, /* BSS set element symbol */ + N_SETB_EXT = 0x1b, + N_SETV = 0x1c, /* Pointer to set vector in data area */ + N_SETV_EXT = 0x1d, + N_WARNING = 0x1e, /* Warning symbol */ + N_FN = 0x1f, /* Filename of .o file */ + N_GSYM = 0x20, /* Global variable */ + N_FNAME = 0x22, /* Function name for BSD Fortran */ + N_FUN = 0x24, /* Function name or text segment variable for C */ + N_STSYM = 0x26, /* Data-segment variable with internal linkage */ + N_LCSYM = 0x28, /* BSS-segment variable with internal linkage */ + N_MAIN = 0x2a, /* Name of main routine */ + N_ROSYM = 0x2c, /* Read-only data symbols */ + N_BNSYM = 0x2e, /* The beginning of a relocatable function block */ + N_PC = 0x30, /* Global symbol in Pascal */ + N_NSYMS = 0x32, /* Number of symbols */ + N_NOMAP = 0x34, /* No DST map for sym */ + N_OBJ = 0x38, /* Like N_SO, but for the object file */ + N_OPT = 0x3c, /* Options for the debugger */ + N_RSYM = 0x40, /* Register variable */ + N_M2C = 0x42, /* Modula-2 compilation unit */ + N_SLINE = 0x44, /* Line number in text segment */ + N_DSLINE = 0x46, /* Line number in data segment */ + N_BSLINE = 0x48, /* Line number in bss segment */ + N_BROWS = 0x48, /* Sun's source-code browser stabs */ + N_DEFD = 0x4a, /* GNU Modula-2 definition module dependency */ + N_FLINE = 0x4c, /* Function start/body/end line numbers */ + N_ENSYM = 0x4e, /* This tells the end of a relocatable function */ + N_EHDECL = 0x50, /* GNU C++ exception variable */ + N_MOD2 = 0x50, /* Modula2 info "for imc" */ + N_CATCH = 0x54, /* GNU C++ `catch' clause */ + N_SSYM = 0x60, /* Structure or union element */ + N_ENDM = 0x62, /* Last stab emitted for module */ + N_SO = 0x64, /* ID for main source file */ + N_OSO = 0x66, /* Apple: This is the stab that associated the .o file */ + N_ALIAS = 0x6c, /* SunPro F77: Name of alias */ + N_LSYM = 0x80, /* Automatic variable in the stack */ + N_BINCL = 0x82, /* Beginning of an include file */ + N_SOL = 0x84, /* ID for sub-source file */ + N_PSYM = 0xa0, /* Parameter variable */ + N_EINCL = 0xa2, /* End of an include file */ + N_ENTRY = 0xa4, /* Alternate entry point */ + N_LBRAC = 0xc0, /* Beginning of lexical block */ + N_EXCL = 0xc2, /* Place holder for deleted include file */ + N_SCOPE = 0xc4, /* Modula-2 scope information */ + N_PATCH = 0xd0, /* Solaris2: Patch Run Time Checker */ + N_RBRAC = 0xe0, /* End of a lexical block */ + N_BCOMM = 0xe2, /* Begin named common block */ + N_ECOMM = 0xe4, /* End named common block */ + N_ECOML = 0xe8, /* Member of a common block */ + N_WITH = 0xea, /* Solaris2: Pascal "with" statement */ + N_NBTEXT = 0xf0, + N_NBDATA = 0xf2, + N_NBBSS = 0xf4, + N_NBSTS = 0xf6, + N_NBLCS = 0xf8, + N_LENG = 0xfe /* Second symbol entry whih a length-value for the preceding entry */ }; enum stab_source_file { - N_SO_AS = 0x01, - N_SO_C = 0x02, - N_SO_ANSI_C = 0x03, - N_SO_CC = 0x04, - N_SO_FORTRAN = 0x05, - N_SO_PASCAL = 0x06, - N_SO_FORTRAN90 = 0x07, - N_SO_OBJC = 0x32, - N_SO_OBJCPLUS = 0x33 + N_SO_AS = 0x01, + N_SO_C = 0x02, + N_SO_ANSI_C = 0x03, + N_SO_CC = 0x04, + N_SO_FORTRAN = 0x05, + N_SO_PASCAL = 0x06, + N_SO_FORTRAN90 = 0x07, + N_SO_OBJC = 0x32, + N_SO_OBJCPLUS = 0x33 }; #endif /* STABS_H_ */ diff --git a/output/strtbl.c b/output/strtbl.c deleted file mode 100644 index 23b0d118..00000000 --- a/output/strtbl.c +++ /dev/null @@ -1,117 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2017 The NASM Authors - All Rights Reserved - * See the file AUTHORS included with the NASM distribution for - * the specific copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following - * conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ----------------------------------------------------------------------- */ - -/* - * Common string table handling - * - * A number of output formats use a "string table"; a container for - * a number of strings which may be reused at will. This implements - * a string table which eliminates duplicates and returns the index - * into the string table when queried. - */ - -#include "compiler.h" - -#include "nasm.h" -#include "nasmlib.h" -#include "error.h" -#include "strtbl.h" - -struct strtbl_entry { - size_t index; - size_t bytes; - char str[1]; -}; - -void strtbl_init(struct nasm_strtbl *tbl) -{ - tbl->size = 0; - hash_init(&tbl->hash, HASH_LARGE); - strtbl_add(tbl, ""); /* Index 0 is always an empty string */ -} - -void strtbl_free(struct nasm_strtbl *tbl) -{ - hash_free_all(&tbl->hash, false); -} - -size_t strtbl_add(struct nasm_strtbl *tbl, const char *str) -{ - void **sep; - struct strtbl_entry *se; - struct hash_insert hi; - - sep = hash_find(&tbl->hash, str, &hi); - if (sep) { - se = *sep; - } else { - size_t bytes = strlen(str) + 1; - - se = nasm_malloc(sizeof(struct strtbl_entry)-1+bytes); - se->index = tbl->size; - tbl->size += bytes; - se->bytes = bytes; - memcpy(se->str, str, bytes); - - hash_add(&hi, se->str, se); - } - - return se->index; -} - -size_t strtbl_find(struct nasm_strtbl *tbl, const char *str) -{ - void **sep; - struct strtbl_entry *se; - - sep = hash_find(&tbl->hash, str, NULL); - if (sep) { - se = *sep; - return se->index; - } else { - return STRTBL_NONE; - } -} - -/* This create a linearized buffer containing the actual string table */ -void *strtbl_generate(const struct nasm_strtbl *tbl) -{ - char *buf = nasm_malloc(strtbl_size(tbl)); - struct hash_tbl_node *iter = NULL; - struct strtbl_entry *se; - - while ((se = hash_iterate(&tbl->hash, &iter, NULL))) - memcpy(buf + se->index, se->str, se->bytes); - - return buf; -} diff --git a/output/strtbl.h b/output/strtbl.h deleted file mode 100644 index 12771e4e..00000000 --- a/output/strtbl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2017 The NASM Authors - All Rights Reserved - * See the file AUTHORS included with the NASM distribution for - * the specific copyright holders. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following - * conditions are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * 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 - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ----------------------------------------------------------------------- */ - -#ifndef NASM_STRTBL_H -#define NASM_STRTBL_H - -#include "compiler.h" -#include "hashtbl.h" - -struct nasm_strtbl { - size_t size; - struct hash_table hash; -}; - -#define STRTBL_NONE ((size_t)-1) - -void strtbl_init(struct nasm_strtbl *tbl); -void strtbl_free(struct nasm_strtbl *tbl); -size_t strtbl_find(struct nasm_strtbl *tbl, const char *str); -size_t strtbl_add(struct nasm_strtbl *tbl, const char *str); -static inline size_t strtbl_size(const struct nasm_strtbl *tbl) -{ - return tbl->size; -} -void * safe_alloc strtbl_generate(const struct nasm_strtbl *tbl); - -#endif /* NASM_STRTBL_H */ |