The "bin" format was misinterpreting the overloading of the "size"
argument to out(), which caused another source of 64-bit relative
offset errors.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
It is unclear if we will ever see any "naked" (absolute bytes)
OUT_REL*ADR coming from the assembler, but if we do, we should
generate them correctly.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Now when the assembler is properly generating the address that we push
down to the backend, enable requesting an exact value for these
relocations (these are pointing to a specific GOT or PLT slot; the
addend is used to adjust the computed value in the instruction, not
for offset for the symbol.)
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
The "size" argument to the OUT_REL*ADR output types is actually
intra-instruction offset, not the actual size. Thus, emit the size
properly.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Fix the arithmetic for relative GOT/PLT references.
We still can't enable exactitude, because of the assumption that
"size" is always the proper adjustment for the offset of the
displacement inside the instruction, which is wrong in the case of
displacements that are followed by an immediate. This also affects
the list file, so it really should be fixed.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
GOTOFF64 is used for local variables (as a 64-bit offset from the GOT;
only needed in the Medium PIC or Large PIC models.) It therefore
should *not* be a elf_add_gsym_reloc() invocation.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
I am having a bit of a hard time understanding the proper operation of
the "exact" flag to elf_add_gsym_reloc(). We apparently won't
generate proper GOTOFF64 relocations with this flag set; it is
possible that there are *no* proper uses of this flag. This clearly
needs to be figured out.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
GOT and PLT references need a symbol; after all, they reference a GOT
or PLT slot. Thus, they need elf_add_gsym_reloc(). Mungify the
interface so that they can communicate the need for the PC-shifted
offset into the relocation.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
When generating an address that is *not* tied to a symbol, we just
want to emit the bytes. I believe the assembler is already supposed
to do that for us, but just in case, do it right here too.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
The x86-64 ABI wants the symbol addend to reside in the addend field
of the RELA relocation, not in the code stream. Apparently it's
something one can get away with, but the linker would still botch it
for some cases. Change it so we pass the proper output and emit zero
into the code stream.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Try to make the various GOT relocations do the right thing in ELF64,
including erring out when appropriate.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Expressions like
mov r15,[rel integer wrt ..got]
lea rax,[rel integer wrt ..gotoff]
now assemble correctly.
In addition, a fix has been made to the corresponding
abs relocations.
Both of these areas still need additional testing.
Somehow the win32 and win64 aliases got listed on Mach-O, not on
COFF. This doesn't have any effect on the current code, but might in
the future. Correct.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Don't use explicit L's for things which are really size_t; not only is
it unnecessarily ugly, but it's wrong in a lot of ways. Do some other
minor stylistic cleanups.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
We would leave the output symbol type uninitialized. Explicitly
initialize it to zero (T_NULL, meaning no symbol type information),
since that's what was effectively done.
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.
Make the WSAA macros contain their own buffer definitions. This
eliminates the need to have a separate "workbuf" declared in the
outelf backends, which isn't even used for anything else, except for a
few completely redundant strcpys.
Note: these macros probably should be replaced with actual
functions. The overhead of the function call is likely to be more
than offset by lower icache footprint.
Guess what, SEH again, but in Win64 context, which is completely
different matter from Win32. At lowest level this one boils down to
putting so called imagerel references, or in practical terms
relocations of type ADDR32NB, 0x0003, into .pdata and .xdata
segments. Two possibilities. 1. implement say 'wrt ..imagerel' or 'wrt
..imagebase'. 2. silently enforce ADDR32NB relocations in .pdata and
.xdata segments.
This is basically not a bug report, but a feature request.
It's desired to be able to link .obj modules compiled with 'nasm -f
win32' with Microsoft 'link /safeseh'. As well as to register symbols
(commonly subroutine's entry points or even external symbols) as "safe
handlers." In order to achieve this, several points are required.
First of all, object module has to have absolute symbol named @feat.00
with value of 1. This can actually be achived by adding 'absolute 1'
and '@feat.00:' to source code, but it's desirable that it's
autogenerated for win32 modules.
Handler registration is essentially symbol's *index* in current
module's symbol table in .sxdata, segment with 0x200 segment flags, an
"info" segment. It's also essential that symbol has type 0x20 (see
below). All this is depicted in following framgents of 'objdump -xD'
output:
Sections:
Idx Name Size VMA LMA File off Algn
0 .sxdata 00000004 00000000 00000000 0000003c 2**2
CONTENTS, READONLY, DEBUGGING
SYMBOL TABLE:
...
[ 5](sec -1)(fl 0x00)(ty 0)(scl 3) (nx 0) 0x00000001 @feat.00
[ 6](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 _handler
...
<.sxdata>
0: 06 00 00 00
Note [6] and (ty 20) in _handle line in SYMBOL TABLE. "06 00 00 00" in
.sxdata is little-endian 6, _handler's index. This is what makes up
"registration." It's impossible to achieve this with current nasm
facilities and it's probably appropriate to introduce a directive for
it, 'safeseh _handler' is probably most natural choice.
When using temporaries in macros, given them a unique prefix to avoid
namespace collisions when using one macro inside another.
Move the WSAA*() macros from outelf32/outelf64 to a separate header
file.
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.
Fix one missed change from "type" to "size". May want to look through
all the other backends as well for similar issues.
This would generate the wrong section lengths, with obviously bad results.
Our size arguments are 64-bit values, but we don't need that range for
anywhere where we need a switch. OpenWatcom can't deal with them
(sigh), so cast them to (int) for now.
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.