mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-04-12 18:40:23 +08:00
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:
parent
a5fb90834a
commit
d1fb15c154
17
assemble.c
17
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;
|
||||
}
|
||||
|
11
compiler.h
11
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 */
|
||||
|
2
disasm.c
2
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))
|
||||
|
2
float.c
2
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)), \
|
||||
|
@ -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
4
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;
|
||||
|
30
nasmlib.c
30
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,
|
||||
|
12
nasmlib.h
12
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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user