For 16-bit and 32-bit x86 code, the size and realsize() always
matches as only jumps, calls and loops uses PC relative
addressing and the address isn't followed by any other opcode
bytes. In 64-bit mode there is RIP relative addressing which
means the fixup location can be followed by an immediate value,
meaning that size > realsize().
When the CPU is calculating the effective address, it takes the
RIP at the end of the instruction and adds the fixed up relative
address value to it.
The linker's point of reference is the end of the fixup location
(which is the end of the instruction for Jcc, CALL, LOOP[cc]).
It is calculating distance between the target symbol and the end
of the fixup location, and add this to the displacement value we
are calculating here and storing at the fixup location.
To get the right effect, we need to _reduce_ the displacement
value by the number of bytes following the fixup.
Example:
data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
end of fixup at 0x054, end of instruction at 0x058.
=> size = 8.
=> realsize() -> 4
=> CPU needs a value of: 0x100 - 0x058 = 0x0a8
=> linker/loader will add: 0x100 - 0x054 = 0x0ac
=> We must add an addend of -4.
=> realsize() - size = -4.
The code used to do size - realsize() at least since v0.90,
probably because it wasn't needed...
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Make the source code easier to understand and keep track of by
organizing it into subdirectories depending on the function.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Split lib/ into nasmlib/ (for nasm-specific functions) and stdlib/
(for replacements for C library functions which may be missing.)
Rename the ersatz inttypes.h to nasmint.h so we can use a simple test
in compiler.h instead of dealing with include path magic.
Remove tests in configure.in for ancient missing functions (which will
break the build anyway.)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Move version strings to a separate header, instead of needing to
include nasm.h in places where it probably really doesn't belong.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Get rid of the completely pointless "debuginfo" parameter to
ofmt->cleanup(). Most backends completely ignore it, and the two that
care (obj, ieee) can simply test dfmt instead.
Also, dfmt is never NULL, so any test for a NULL dfmt is bogus.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
labels.c now filter ..[^@] special symbols from the debug backend, so
we don't have to open-code that everywhere.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Cc: Jim Kukunas <james.t.kukunas@linux.intel.com>
Move ofmt->current_dfmt into a separate global variable. This
should allow us to make ofmt readonly and removes some additional
gratuitious differences between backends.
From master branch checkin a7bc15dd0a
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
We pass around a whole bunch of function pointers in arguments,
which then just get stashed in static variables. Clean this mess
up and in particular handle the error management in the preprocessor
using nasm_set_verror() which already exists.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
From master branch checkin 130736c0cf
Resolved Conflicts:
nasm.c
preproc-nop.c
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Replace all instances of ERR_FATAL or ERR_PANIC with nasm_fatal or
nasm_panic so the compiler knows that these functions cannot return,
*and* we trigger abort() if we were to ever violate that constraint.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Make struct dfmt and the struct dfmt arrays const across the board,
and make them static whereever possible.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Move ofmt->current_dfmt into a separate global variable. This
should allow us to make ofmt readonly and removes some additional
gratuitious differences between backends.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
We pass around a whole bunch of function pointers in arguments,
which then just get stashed in static variables. Clean this mess
up and in particular handle the error management in the preprocessor
using nasm_set_verror() which already exists.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
size is actually an uint64_t, and LLVM drops the abs() on the
principle that the uint64_t should always be positive. Make it
explicit that we are converting to a signed integer first, by using
abs((int)size) instead.
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Instead of having unchecked fwrite() calls, introduce nasm_write()
which does error checking (and fatal errors if the write fails).
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
We could have accessed malloc'ed data on external symbols
in obj and ieee output formats. Fix it by using nasm_zalloc.
Reported-by: Jiri Malak
Patch-by: Jiri Malak
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Instead of manipulating stdscan buffer pointer directly
we switch to a routine interface.
This allow us to unify stdscan access: ie caller should
"talk" to stdscan via stdscan_get/set routines.
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This is the null implementation of the function debug_directive. For
some reason it ended up getting mangled as "null_debug_routine".
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
We never set ofmt and errfunc to anything but the global values.
Dropping them from the label definition function command line
simplifies the code.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Remove a bunch of function pointers in the output stage; they are
never changed and don't add any value. Also make "ofile" a global
variable and let the backend use it directly.
All we ever did with these variables were stashing it in locals and
using them as-is anyway for no benefit.
Also change the global error function, nasm_error() into a true
function which invokes a function pointer internally. That lets us
use direct calls to it.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Hash all directives, even the ones that are backend-specific,
and instead pass the backend an already-parsed directive number.
Furthermore, unify null functions across various backends.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Allow the backend to specify that an output format is either text or
binary. For future uses, define this as a flag word so we can define
other flags in the future if it would make sense.
Currently, the ieee and dbg formats are text; all the others are
binary.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
SEG <undefined> can happen, validly, for a common symbol during the
optimization passes. It better not happen during the real passes,
however!
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Add new copyright headers to the new output modules. As far as I
know, the only module which we still don't have a green light to
release under 2-BSD is outmacho.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Move the prototypes for the null debugging format to outform.h (for
the top-level structure declaration only) and outlib.h (for the
internal routines.)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Move backend-specific code into the output/ directory, and make the
null debugging backend a separate file (it certainly isn't needed for
ndisasm...)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
We already call current_dfmt->init in the same place (at the very end
of ofmt->init) in all the backends that do it; instead call it
centrally in nasm.c after ofmt->init.
This fixes invalid ELF files with when compiling with -F dwarf, since
the dwarf initialization routine never got called.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
nasm.c should respect the default debug format of the output format,
instead of replacing it with the first format in the list.
This is cleaner and allows the list to be sorted normally.
This commit rewrites commit 116994111b which was very fragile.
Move all the version strings to a single compilation unit, ver.c; this
does not include the version macros, which are fed into macros.c.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Add a common file, outlib.c, for output formats. Add the function
realsize() instead of open-coded variants in almost every backend.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
The testcase illustrates the problem. After "nasm -f obj
alonesym.nasm"
let's look to dump:
======
PUBDEF386(91) recnum:5, offset:0000005bh, len:03f9h, chksum:bbh(bb)
Group: 0, Seg: 1
00020000h - 'sym0000' Type:0
00020004h - 'sym0001' Type:0
....
00020134h - 'sym0077' Type:0
PUBDEF(90) recnum:6, offset:00000457h, len:000ah, chksum:b6h(b6)
Group: 0, Seg: 1
00000138h - 's' Type:2
0000b600h - '' Type:0
======
The problem is while 's' offset is 20138h it is marked as type 90h not
91h. The root cause is located in obj_x():
static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
{
if (orp->type & 1)
orp->x_size = 32;
if (val > 0xFFFF)
orp = obj_force(orp, 32);
if (orp->x_size == 32)
return (obj_dword(orp, val));
orp->x_size = 16;
return (obj_word(orp, val));
}
It sets up x_size and than writes data. In the testcase data are the
offset and this offset overflows a record. In this case the record is
emitted and its x_size is cleared. Because this is last PUBDEF the new
record with only 's' symbol is emitted also but its x_size is not 32
(it's still zero) so obj_fwrite doesn't switch to 91h type.
The problem seems to be very generic and expected to be occurred on
many other record types as well.
----
And the fix is simple:
if (orp->x_size == 32)
{
ObjRecord * nxt = obj_dword(orp, val);
nxt->x_size = 32; /* x_size is cleared when a record overflows */
return nxt;
}
ctype functions take an *int*, which the user is expected to have
taken the input character from getc() and friends, or taken a
character and cast it to (unsigned char).
We don't care about EOF (-1), so use macros that cast to (unsigned
char) for us.
Move the handling of "extra" macros (i.e. output format macros) into
the macros.pl mechanism. This allows us to change the format of the
internal macro store in the future - e.g. to a single byte store
without redundant pointers.
Also, stop using indicies into a long array when there is no good
reason to not just use different arrays.
Clean up remaining build warnings. None of this should affect code
operations. The only warnings which were actually relevant might have
been the ones in ldrdf.c, but it's not clear if anyone ever uses that.