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.
This commit is contained in:
H. Peter Anvin 2007-11-13 09:37:59 -08:00
parent a5fb90834a
commit d1fb15c154
20 changed files with 81 additions and 96 deletions

View file

@ -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;
}

View file

@ -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 */

View file

@ -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))

View file

@ -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)), \

View file

@ -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';
}

4
nasm.c
View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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);
}
}

View file

@ -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);
}