summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-11-13 09:37:59 -0800
committerH. Peter Anvin <hpa@zytor.com>2007-11-13 09:37:59 -0800
commitd1fb15c154b99f9ca8d2356fa9057827b0ab89af (patch)
treee6e95a1979107466eadfad29577e278ee1273890
parenta5fb90834aa2e849e67bf45b478d498a6cb72062 (diff)
downloadnasm-d1fb15c154b99f9ca8d2356fa9057827b0ab89af.tar.gz
nasm-d1fb15c154b99f9ca8d2356fa9057827b0ab89af.tar.bz2
nasm-d1fb15c154b99f9ca8d2356fa9057827b0ab89af.zip
Address data is int64_t; simplify writing an address object
Address data is always int64_t even if the size itself is smaller; this was broken on bigendian hosts (still need testing!) Create simple "write sized object" macros.
-rw-r--r--assemble.c17
-rw-r--r--compiler.h11
-rw-r--r--disasm.c2
-rw-r--r--float.c2
-rw-r--r--listing.c2
-rw-r--r--nasm.c4
-rw-r--r--nasmlib.c30
-rw-r--r--nasmlib.h12
-rw-r--r--output/outaout.c6
-rw-r--r--output/outas86.c8
-rw-r--r--output/outbin.c13
-rw-r--r--output/outcoff.c8
-rw-r--r--output/outdbg.c8
-rw-r--r--output/outelf32.c6
-rw-r--r--output/outelf64.c8
-rw-r--r--output/outieee.c2
-rw-r--r--output/outmacho.c9
-rw-r--r--output/outobj.c2
-rw-r--r--output/outrdf.c14
-rw-r--r--output/outrdf2.c13
20 files changed, 81 insertions, 96 deletions
diff --git a/assemble.c b/assemble.c
index a56887e..2d24e8d 100644
--- a/assemble.c
+++ b/assemble.c
@@ -181,18 +181,13 @@ static void out(int64_t offset, int32_t segto, const void *data,
* convert it into RAWDATA format.
*/
uint8_t *q = p;
-
- switch (size) {
- case 2:
- WRITESHORT(q, *(int32_t *)data);
- break;
- case 4:
- WRITELONG(q, *(int32_t *)data);
- break;
- case 8:
- WRITEDLONG(q, *(int64_t *)data);
- break;
+
+ if (size > 8) {
+ errfunc(ERR_PANIC, "OUT_ADDRESS with size > 8");
+ return;
}
+
+ WRITEADDR(q, *(int64_t *)data, size);
data = p;
type = OUT_RAWDATA;
}
diff --git a/compiler.h b/compiler.h
index 6e9e37e..b660855 100644
--- a/compiler.h
+++ b/compiler.h
@@ -96,4 +96,15 @@ int strnicmp(const char *, const char *, size_t);
char *strsep(char **, const char *);
#endif
+/*
+ * Define this to 1 for faster performance if this is a littleendian
+ * platform which can do unaligned memory references. It is safe
+ * to leave it defined to 0 even if that is true.
+ */
+#if defined(__i386__) || defined(__x86_64__)
+# define X86_MEMORY 1
+#else
+# define X86_MEMORY 0
+#endif
+
#endif /* NASM_COMPILER_H */
diff --git a/disasm.c b/disasm.c
index 139e8d2..18911f0 100644
--- a/disasm.c
+++ b/disasm.c
@@ -53,7 +53,7 @@ struct prefix_info {
};
#define getu8(x) (*(uint8_t *)(x))
-#if defined(__i386__) || defined(__x86_64__)
+#if X86_MEMORY
/* Littleendian CPU which can handle unaligned references */
#define getu16(x) (*(uint16_t *)(x))
#define getu32(x) (*(uint32_t *)(x))
diff --git a/float.c b/float.c
index eddb719..c4582cd 100644
--- a/float.c
+++ b/float.c
@@ -45,7 +45,7 @@ typedef uint64_t fp_2limb;
#define LIMB_ALL_BYTES ((fp_limb)0x01010101)
#define LIMB_BYTE(x) ((x)*LIMB_ALL_BYTES)
-#if defined(__i386__) || defined(__x86_64__)
+#if X86_MEMORY
#define put(a,b) (*(uint32_t *)(a) = (b))
#else
#define put(a,b) (((a)[0] = (b)), \
diff --git a/listing.c b/listing.c
index 64ad348..e4da7cb 100644
--- a/listing.c
+++ b/listing.c
@@ -75,7 +75,7 @@ static void list_emit(void)
if (listlinep)
fprintf(listfp, " %s", listline);
- fputc('\n', listfp);
+ putc('\n', listfp);
listlinep = false;
listdata[0] = '\0';
}
diff --git a/nasm.c b/nasm.c
index 880d0a5..95960bb 100644
--- a/nasm.c
+++ b/nasm.c
@@ -155,7 +155,7 @@ static void nasm_fputs(const char *line, FILE * outfile)
{
if (outfile) {
fputs(line, outfile);
- fputc('\n', outfile);
+ putc('\n', outfile);
} else
puts(line);
}
@@ -1608,7 +1608,7 @@ static void report_error_common(int severity, const char *fmt,
}
vfprintf(error_file, fmt, args);
- fputc('\n', error_file);
+ putc('\n', error_file);
if (severity & ERR_USAGE)
want_usage = true;
diff --git a/nasmlib.c b/nasmlib.c
index 170c95f..b89c711 100644
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -363,28 +363,30 @@ int32_t seg_alloc(void)
void fwriteint16_t(int data, FILE * fp)
{
- fputc((int)(data & 255), fp);
- fputc((int)((data >> 8) & 255), fp);
+ char buffer[2], *p = buffer;
+ WRITESHORT(p, data);
+ fwrite(buffer, 1, 2, fp);
}
void fwriteint32_t(int32_t data, FILE * fp)
{
- fputc((int)(data & 255), fp);
- fputc((int)((data >> 8) & 255), fp);
- fputc((int)((data >> 16) & 255), fp);
- fputc((int)((data >> 24) & 255), fp);
+ char buffer[4], *p = buffer;
+ WRITELONG(p, data);
+ fwrite(buffer, 1, 4, fp);
}
void fwriteint64_t(int64_t data, FILE * fp)
{
- fputc((int)(data & 255), fp);
- fputc((int)((data >> 8) & 255), fp);
- fputc((int)((data >> 16) & 255), fp);
- fputc((int)((data >> 24) & 255), fp);
- fputc((int)((data >> 32) & 255), fp);
- fputc((int)((data >> 40) & 255), fp);
- fputc((int)((data >> 48) & 255), fp);
- fputc((int)((data >> 56) & 255), fp);
+ char buffer[8], *p = buffer;
+ WRITEDLONG(p, data);
+ fwrite(buffer, 1, 8, fp);
+}
+
+void fwriteaddr(int64_t data, int size, FILE * fp)
+{
+ char buffer[8], *p = buffer;
+ WRITEADDR(p, data, size);
+ fwrite(buffer, 1, size, fp);
}
void standard_extension(char *inname, char *outname, char *extension,
diff --git a/nasmlib.h b/nasmlib.h
index 560ec1e..2e18f10 100644
--- a/nasmlib.h
+++ b/nasmlib.h
@@ -209,12 +209,24 @@ void standard_extension(char *inname, char *outname, char *extension,
WRITECHAR(p,(v) >> 56); \
} while (0)
+#define WRITEADDR(p,v,s) \
+ do { \
+ int _s = (s); \
+ uint64_t _v = (v); \
+ while (_s--) { \
+ WRITECHAR(p,_v); \
+ _v >>= 8; \
+ } \
+ } while(0)
+
/*
* and routines to do the same thing to a file
*/
+#define fwriteint8_t(d,f) putc(d,f)
void fwriteint16_t(int data, FILE * fp);
void fwriteint32_t(int32_t data, FILE * fp);
void fwriteint64_t(int64_t data, FILE * fp);
+void fwriteaddr(int64_t data, int size, FILE * fp);
/*
* Routines to manage a dynamic random access array of int32_ts which
diff --git a/output/outaout.c b/output/outaout.c
index a359b94..fec1262 100644
--- a/output/outaout.c
+++ b/output/outaout.c
@@ -622,7 +622,7 @@ static void aout_out(int32_t segto, const void *data,
error(ERR_PANIC, "OUT_RAWDATA with other than NO_SEG");
aout_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) {
- addr = *(int32_t *)data;
+ addr = *(int64_t *)data;
if (segment != NO_SEG) {
if (segment % 2) {
error(ERR_NONFATAL, "a.out format does not support"
@@ -699,7 +699,7 @@ static void aout_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITESHORT(p, *(int32_t *)data - (size + s->len));
+ WRITESHORT(p, *(int64_t *)data - (size + s->len));
aout_sect_write(s, mydata, 2L);
} else if (type == OUT_REL4ADR) {
if (segment == segto)
@@ -729,7 +729,7 @@ static void aout_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - (size + s->len));
+ WRITELONG(p, *(int64_t *)data - (size + s->len));
aout_sect_write(s, mydata, 4L);
}
}
diff --git a/output/outas86.c b/output/outas86.c
index f342314..476e8c9 100644
--- a/output/outas86.c
+++ b/output/outas86.c
@@ -320,12 +320,12 @@ static void as86_out(int32_t segto, const void *data,
error(ERR_NONFATAL, "as86 format does not support"
" segment base references");
} else {
- offset = *(int32_t *)data;
+ offset = *(int64_t *)data;
as86_add_piece(s, 1, offset, segment, size, 0);
}
} else {
p = mydata;
- WRITELONG(p, *(int32_t *)data);
+ WRITELONG(p, *(int64_t *)data);
as86_sect_write(s, data, size);
as86_add_piece(s, 0, 0L, 0L, size, 0);
}
@@ -337,7 +337,7 @@ static void as86_out(int32_t segto, const void *data,
error(ERR_NONFATAL, "as86 format does not support"
" segment base references");
} else {
- offset = *(int32_t *)data;
+ offset = *(int64_t *)data;
as86_add_piece(s, 1, offset - size + 2, segment, 2L,
1);
}
@@ -350,7 +350,7 @@ static void as86_out(int32_t segto, const void *data,
error(ERR_NONFATAL, "as86 format does not support"
" segment base references");
} else {
- offset = *(int32_t *)data;
+ offset = *(int64_t *)data;
as86_add_piece(s, 1, offset - size + 4, segment, 4L,
1);
}
diff --git a/output/outbin.c b/output/outbin.c
index d5ec3c7..68c5d95 100644
--- a/output/outbin.c
+++ b/output/outbin.c
@@ -788,12 +788,7 @@ static void bin_out(int32_t segto, const void *data,
if (segment != NO_SEG)
add_reloc(s, size, segment, -1L);
p = mydata;
- if (size == 4)
- WRITELONG(p, *(int32_t *)data);
- else if (size == 8)
- WRITEDLONG(p, *(int64_t *)data);
- else
- WRITESHORT(p, *(int32_t *)data);
+ WRITEADDR(p, *(int64_t *)data, size);
saa_wbytes(s->contents, mydata, size);
}
s->length += size;
@@ -836,11 +831,7 @@ static void bin_out(int32_t segto, const void *data,
if (s->flags & TYPE_PROGBITS) {
add_reloc(s, size, segment, segto);
p = mydata;
- /* XXX: WHAT ABOUT SIZE == 8? */
- if (size == 4)
- WRITELONG(p, *(int32_t *)data - size - s->length);
- else
- WRITESHORT(p, *(int32_t *)data - size - s->length);
+ WRITEADDR(p, *(int64_t *)data - size - s->length, size);
saa_wbytes(s->contents, mydata, size);
}
s->length += size;
diff --git a/output/outcoff.c b/output/outcoff.c
index 95a1603..9be558b 100644
--- a/output/outcoff.c
+++ b/output/outcoff.c
@@ -533,7 +533,7 @@ static void coff_out(int32_t segto, const void *data,
fix = coff_add_reloc(s, segment, false, false);
}
p = mydata;
- WRITELONG(p, *(int32_t *)data + fix);
+ WRITELONG(p, *(int64_t *)data + fix);
coff_sect_write(s, mydata, size);
}
} else {
@@ -555,7 +555,7 @@ static void coff_out(int32_t segto, const void *data,
coff_sect_write(s, mydata, size);
} else {
fix = coff_add_reloc(s, segment, false, false);
- WRITELONG(p, *(int32_t *)data + fix);
+ WRITELONG(p, *(int64_t *)data + fix);
coff_sect_write(s, mydata, size);
}
}
@@ -577,9 +577,9 @@ static void coff_out(int32_t segto, const void *data,
fix = coff_add_reloc(s, segment, true, false);
p = mydata;
if (win32 | win64) {
- WRITELONG(p, *(int32_t *)data + 4 - size + fix);
+ WRITELONG(p, *(int64_t *)data + 4 - size + fix);
} else {
- WRITELONG(p, *(int32_t *)data - (size + s->len) + fix);
+ WRITELONG(p, *(int64_t *)data - (size + s->len) + fix);
}
coff_sect_write(s, mydata, 4L);
}
diff --git a/output/outdbg.c b/output/outdbg.c
index 07e1b08..a139699 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -125,13 +125,7 @@ static void dbg_out(int32_t segto, const void *data,
fprintf(dbgf, "\n");
break;
case OUT_ADDRESS:
- ldata = 0; /* placate gcc */
- if (size == 1)
- ldata = *((char *)data);
- else if (size == 2)
- ldata = *((int16_t *)data);
- else if (size == 4)
- ldata = *((int32_t *)data);
+ ldata = *(int64_t *)data;
fprintf(dbgf, "addr %08lx (seg %08lx, wrt %08lx)\n", ldata,
segment, wrt);
break;
diff --git a/output/outelf32.c b/output/outelf32.c
index 8599a65..4976942 100644
--- a/output/outelf32.c
+++ b/output/outelf32.c
@@ -841,7 +841,7 @@ static void elf_out(int32_t segto, const void *data,
elf_sect_write(s, data, size);
} else if (type == OUT_ADDRESS) {
bool gnu16 = false;
- addr = *(int32_t *)data;
+ addr = *(int64_t *)data;
if (segment != NO_SEG) {
if (segment % 2) {
error(ERR_NONFATAL, "ELF format does not support"
@@ -916,7 +916,7 @@ static void elf_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITESHORT(p, *(int32_t *)data - size);
+ WRITESHORT(p, *(int64_t *)data - size);
elf_sect_write(s, mydata, 2L);
} else if (type == OUT_REL4ADR) {
if (segment == segto)
@@ -941,7 +941,7 @@ static void elf_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - size);
+ WRITELONG(p, *(int64_t *)data - size);
elf_sect_write(s, mydata, 4L);
}
}
diff --git a/output/outelf64.c b/output/outelf64.c
index d364268..dcf3def 100644
--- a/output/outelf64.c
+++ b/output/outelf64.c
@@ -798,8 +798,8 @@ static void elf_out(int32_t segto, const void *data,
#if defined(DEBUG) && DEBUG>2
fprintf(stderr,
- " elf_out type: %x seg: %d bytes: %x data: %x\n",
- (type >> 24), segment, size, *(int32_t *)data);
+ " elf_out type: %x seg: %d bytes: %x data: %"PRIx64"\n",
+ (type >> 24), segment, size, *(int64_t *)data);
#endif
/*
@@ -951,7 +951,7 @@ static void elf_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITESHORT(p, *(int32_t *)data - size);
+ WRITESHORT(p, *(int64_t *)data - size);
elf_sect_write(s, mydata, 2L);
} else if (type == OUT_REL4ADR) {
if (segment == segto)
@@ -976,7 +976,7 @@ static void elf_out(int32_t segto, const void *data,
}
}
p = mydata;
- WRITELONG(p, *(int32_t *)data - size);
+ WRITELONG(p, *(int64_t *)data - size);
elf_sect_write(s, mydata, 4L);
}
}
diff --git a/output/outieee.c b/output/outieee.c
index 431a6d8..93a27b5 100644
--- a/output/outieee.c
+++ b/output/outieee.c
@@ -418,7 +418,7 @@ static void ieee_out(int32_t segto, const void *data,
if (segment == NO_SEG && type != OUT_ADDRESS)
error(ERR_NONFATAL, "relative call to absolute address not"
" supported by IEEE format");
- ldata = *(int32_t *)data;
+ ldata = *(int64_t *)data;
if (type == OUT_REL2ADR)
ldata += (size - 2);
if (type == OUT_REL4ADR)
diff --git a/output/outmacho.c b/output/outmacho.c
index 802ea97..14633f4 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -464,7 +464,7 @@ static void macho_output(int32_t secto, const void *data,
break;
case OUT_ADDRESS:
- addr = *(int32_t *)data;
+ addr = *(int64_t *)data;
if (section != NO_SEG) {
if (section % 2) {
@@ -475,12 +475,7 @@ static void macho_output(int32_t secto, const void *data,
}
p = mydata;
-
- if (size == 2)
- WRITESHORT(p, addr);
- else
- WRITELONG(p, addr);
-
+ WRITEADDR(p, addr, size);
sect_write(s, mydata, size);
break;
diff --git a/output/outobj.c b/output/outobj.c
index 95339e2..3dfbf96 100644
--- a/output/outobj.c
+++ b/output/outobj.c
@@ -1061,7 +1061,7 @@ static void obj_out(int32_t segto, const void *data,
if (segment >= SEG_ABS)
error(ERR_NONFATAL, "far-absolute relocations not supported"
" by OBJ format");
- ldata = *(int32_t *)data;
+ ldata = *(int64_t *)data;
if (type == OUT_REL2ADR) {
ldata += (size - 2);
size = 2;
diff --git a/output/outrdf.c b/output/outrdf.c
index 23e661e..9c3785b 100644
--- a/output/outrdf.c
+++ b/output/outrdf.c
@@ -392,16 +392,8 @@ static void rdf_out(int32_t segto, void *data, uint32_t type,
}
pd = databuf; /* convert address to little-endian */
- if (bytes == 4)
- WRITELONG(pd, *(int32_t *)data);
- else if (bytes == 8)
- WRITEDLONG(pd, *(int64_t *)data);
- else
- WRITESHORT(pd, *(int32_t *)data);
-
-
+ WRITEADDR(pd, *(int64_t *)data, bytes);
membufwrite(seg[segto], databuf, bytes);
-
} else if (type == OUT_REL2ADR) {
if (segment == segto)
error(ERR_PANIC, "intra-segment OUT_REL2ADR");
@@ -422,7 +414,7 @@ static void rdf_out(int32_t segto, void *data, uint32_t type,
* address of imported symbol onto it to get address relative to end of
* instruction: import_address + data(offset) - end_of_instrn */
- rr.offset = *(int32_t *)data - (rr.offset + bytes);
+ rr.offset = *(int64_t *)data - (rr.offset + bytes);
membufwrite(seg[segto], &rr.offset, -2);
} else if (type == OUT_REL4ADR) {
@@ -440,7 +432,7 @@ static void rdf_out(int32_t segto, void *data, uint32_t type,
rr.refseg = segment; /* segment referred to */
write_reloc_rec(&rr);
- rr.offset = *(int32_t *)data - (rr.offset + bytes);
+ rr.offset = *(int64_t *)data - (rr.offset + bytes);
membufwrite(seg[segto], &rr.offset, -4);
}
}
diff --git a/output/outrdf2.c b/output/outrdf2.c
index 980d113..5bc00d5 100644
--- a/output/outrdf2.c
+++ b/output/outrdf2.c
@@ -583,15 +583,8 @@ static void rdf2_out(int32_t segto, const void *data,
}
pd = databuf; /* convert address to little-endian */
- if (size == 4)
- WRITESHORT(pd, *(int32_t *)data);
- else if (size == 8)
- WRITEDLONG(pd, *(int64_t *)data);
- else
- WRITESHORT(pd, *(int32_t *)data);
-
+ WRITEADDR(pd, *(int64_t *)data, size);
membufwrite(segto, databuf, size);
-
} else if (type == OUT_REL2ADR) {
if (segment == segto)
error(ERR_PANIC, "intra-segment OUT_REL2ADR");
@@ -609,7 +602,7 @@ static void rdf2_out(int32_t segto, const void *data,
/* what do we put in the code? Simply the data. This should almost
* always be zero, unless someone's doing segment arithmetic...
*/
- rr.offset = *(int32_t *)data;
+ rr.offset = *(int64_t *)data;
} else {
rr.type = RDFREC_RELOC; /* type signature */
rr.segment = segto + 64; /* segment we're currently in + rel flag */
@@ -639,7 +632,7 @@ static void rdf2_out(int32_t segto, const void *data,
rr.reclen = 8;
write_reloc_rec(&rr);
- rr.offset = *(int32_t *)data - (rr.offset + size);
+ rr.offset = *(int64_t *)data - (rr.offset + size);
membufwrite(segto, &rr.offset, -4);
}