Previously a line such as "times 4 mov rax, [rel foobar]" would result
in incorrect relocations being generated.
Patch by: bird-yasm@anduin.net
[#211 state:resolved]
Don't generate an additional offset for _GLOBAL_OFFSET_TABLE_ if a WRT was
specified (the NASM usage). In GAS, _GLOBAL_OFFSET_TABLE_ doesn't have a WRT
but instead has special handling.
This isn't quite *exactly* the right fix; a better fix would be to recognize
the _GLOBAL_OFFSET_TABLE_ case in the GAS parser and adjust the value
appropriately there. However, this fix seems to do the right thing in the
meantime for both GAS and NASM cases.
svn path=/trunk/yasm/; revision=2321
This was particularly noticable in GAS, but there was also a bug in NASM
output (lack of fixup within instruction in elf32).
Also:
- changed ssym lookup from a linear search to using assocdata
- added more relocation types (most not implemented)
Reported by: Mark Charney
svn path=/trunk/yasm/; revision=2206
- symbol is defined in a TLS section
- symbol is used in a TLS relocation
This is required by the GNU linker, and matches GNU as behavior.
The implementation is not as clean as it perhaps should be, but it does
the job.
Reported by: Nils Weller <nils@gnulinux.nl>
svn path=/trunk/yasm/; revision=2040
Reported by: Loren Merritt
Fix by: mu@
We already had a testcase for this, but it had an incorrect "golden" result.
svn path=/trunk/yasm/; revision=1952
been using a mix of tabs and 4 spaces to indent; this looks horrible if
tab size is ever not 8. While I debated converting to tab-only indentation
that would have been a far higher impact to the source.
svn path=/trunk/yasm/; revision=1825
and common declare. The latter no longer passes through objfmt at parse time;
instead the objfmt must handle them at output time (objfmt-specific
extensions are parsed & stored by the parser). Directives are now handled
using a list (with function pointers) rather than a single function entry
point.
svn path=/trunk/yasm/; revision=1819
NASM behavior with regards to e.g. extern $foo.
Unfortunately this makes yasm start not matching NASM behavior with regards
to the RDF module directive. In NASM, module $foo results in a literal $foo
reference; yasm now requires either a double $ (e.g. $$foo) or quotes (e.g.
"$foo"). The special case for section (section $foo --> literal $foo) is
still present, but keeping this for other directives is extremely difficult.
svn path=/trunk/yasm/; revision=1754
(such as the common .note.GNU-stack section). While Yasm allows such section
names by enclosing with double-quotes, NASM allows this, so for compatibility
it makes sense for Yasm to as well.
svn path=/trunk/yasm/; revision=1723
(sym in other section)-(sym in this section) rather than just
(sym in other section)-(curpos) (e.g. sym-$). Unfortunately supporting
this required precbc to be flowed down to the value_finalize functions,
but it's relatively reasonable to do so, as all of the _finalize() routines
have access to precbc.
Reported by: Peter Tanski <peter_tanski@cox.net>
svn path=/trunk/yasm/; revision=1705
other testcase changes).
While I'm here, fix handling of arith [], dword X in 64-bit mode by making
this an error; it's impossible to tell if add dword [], X or add qword [], X
is meant as the immediate part is always a dword. This is only important for
arith rather than other memory instructions due to dword also being needed
for optimization.
Next step: support strict for jump sizing and optimize non-strict sized
jumps.
svn path=/trunk/yasm/; revision=1680
PC-relative relocations (jumps and calls).
- Allow SEG:OFF to be used as just an offset portion (like NASM does).
- Labels in absolute sections that are declared global are given the correct
absolute value in the symbol table.
One difference from NASM:
label equ 0040h:001eh
jmp label
in NASM means the same as:
jmp 001eh (a near jump)
but yasm will treat this the same as:
jmp 0040h:001eh (a far jump)
I'm still not completely happy with this implementation, but it's workable
and fixes all the bugs I've found so far in absolute handling.
svn path=/trunk/yasm/; revision=1634
exception handling. There are now two layers an error or warning goes
through before it hits the user: first an error is logged via
yasm_error_set() (or yasm_warn_set() for a warning). Only one error may
be set, whereas multiple warnings can be set (yasm_warn_set maintains a
linked list). Then, calling yasm_errwarn_propagate() propagates any error
and/or warning(s) to an errwarns structure and associates the
errors/warnings with a line number at that time; this call also clears the
pending errors/warnings and allows new ones to be set. The propagate
function can safely be called when there are no pending error/warnings.
In addition, there are some helper errwarn functions that allow clearing of
an error/warning without propagating, getting it separately, etc.
Still yet to be done: changing most/all uses of yasm_internal_error() into
yasm_error_set(YASM_ERROR_ASSERTION).
The main advantage this change has is making libyasm functions feel much
more library like, and separating the user code line numbers from the inner
function error handling (e.g. intnum create functions only needed the line
number to trigger errors; this is no longer required).
The set/propagate/etc functions use global data structures to avoid passing
around a pointer to every function. This would need to be made thread-local
data in a threaded app. Errwarns containers (that keep associated line
numbers) are no longer global, so multiple source streams can be processed
separately with no conflict (at least if there's only a single thread of
execution).
svn path=/trunk/yasm/; revision=1521
is support for cross-section relative symbol references using "sym-$".
This generates a 32-bit relative relocation similar to those used for
cross-section jumps and calls.
The bugfix is that in Win64 output, RIP-relative relocations do something
special when there is an immediate value (or anything else) between the
value being relocated and the next instruction. E.g.
"shl dword [sym wrt rip], 5" needs to generate a REL32_1 relocation thanks
to the immediate byte following the RIP-relative value.
* symrec.c (sym_type): add SYM_CURPOS to track labels representing the
current assembly position (e.g. $ in NASM, . in GAS).
(yasm_symtab_define_curpos): New function to create symbols of this type.
(yasm_symrec_is_curpos): Check to see if symbol is SYM_CURPOS type.
(yasm_symrec_get_label, yasm_symrec_print): Update to handle SYM_CURPOS.
* symrec.h (yasm_symtab_define_curpos): Prototype.
(yasm_symrec_is_curpos): Prototype.
* gas-bison.y: Use yasm_symtab_define_curpos when defining '.'.
* nasm-bison.y: Use yasm_symtab_define_curpos when defining '$'.
* value.c (yasm_value_finalize_expr): Look for cross-section
"sym-SYM_CURPOS" combinations and generate curpos-relative value if found.
* coretype.h (yasm_value): Add ip_rel member to designate that curpos_rel
is set due to the value being IP-relative (rather than sym-curpos).
* value.h (yasm_value_initialize, yasm_value_init_sym): Initialize ip_rel.
* x86expr.c (yasm_x86__check_ea): Set ip_rel in addition to curpos_rel if
detected WRT rip.
* x86bc.c (x86_bc_insn_tobytes): Use ip_rel instead of curpos_rel when
adjusting for RIP-relative.
* coff-objfmt.c (coff_objfmt_output_value): Properly adjust output and
generate correct relocations for both curpos_rel and ip_rel. This
includes new generation of REL32_1, REL32_2, etc relocations.
* symrec.c, symrec.h (yasm_symtab_define_label2): Delete.
* coff-objfmt.c (stabs_debgfmt_generate_sections): Change to use
yasm_symtab_define_label() instead.
* win32-curpos.asm, win64-curpos.asm, curpos.asm, curpos-err.asm,
elf_gas64_curpos.asm: New tests for above.
svn path=/trunk/yasm/; revision=1423
The fix for this rippled into a lot of places, and I'm starting to see some
opportunities for cleaning up some of the object and objfmt structures.
* objfmt.h (yasm_objfmt_add_default_section): Move from standalone function
into objfmt-specific function.
(yasm_objfmt_module): Remove default_section_name string, and add objfmt
specific add_default_section function.
* yasm.c (main): Use slightly updated parameters when calling.
* section.h (yasm_section_is_default, yasm_section_set_default): New.
* section.c (yasm_section): Add def member (for default section flag).
(yasm_section_is_default, yasm_section_set_default): Implement.
* xdf-objfmt.c, bin-objfmt.c, dbg-objfmt.c, coff-objfmt.c: Implement.
Usually this required refactoring the objfmt-specific section data creation
into a separate function that could be used by both section_switch() and
the new add_default_section() functions, and changing section_switch() to
update changes to the section data if section was new or previously just a
default section, instead of the previous behavior of warning if the section
was not new.
* objfmt.c: Delete (no longer needed).
* Makefile.inc, Makefile.flat, libyasm.vcproj
Makefile.dj: Update to reflect removal.
* xdf-overdef.asm, win32-overdef.asm, elf-overdef.asm: Test.
svn path=/trunk/yasm/; revision=1390
alignment bytecode rather than just times'ing a NOP. This generates better
NOP code.
The new align only triggers when the NASM align directive is used unadorned
or with nop as the parameter (e.g. "align 16" or "align 16, nop"). Other
uses, including all uses of balign, maintain their old NASM behavior. This
is somewhat useful if you still want a string of NOPs rather than more
optimized instruction patterns: just use "balign X, nop" rather than
"align X". The new align also follows the GAS behavior of increasing the
section's alignment to be the specified alignment (if not already larger).
While I was in here, I found and fixed a bug in 16-bit alignment generation
(typo). I also changed the x86 32-bit code alignment fill pattern per
suggestions in the AMD x86 code optimization manual.
* nasm-bison.y: Implement a new [align] directive that can take a single
parameter (the alignment) and generate a nop-generating align bytecode.
* standard.mac: Change align macro to generate [align] if the second
macro parameter is nonexistent or "nop".
* x86arch.c (x86_get_fill): Update 32-bit fill pattern and fix bug in 16-bit
fill pattern.
svn path=/trunk/yasm/; revision=1389
unsigned char. This was causing relocation corruption after 255 symbols,
in ELF32 only.
* elfmanysym.asm: Additional test that has exactly 257 symbols.
We actually should have caught this with the very large 32-bit elf-x86id.asm
test, but that object file (unlike the 64-bit GAS version of it) has only
been manually reviewed. This bug was only in ELF32, and wasn't in ELF64.
Fixes bug #62 submitted by: Jens von der Heydt <mailme@vdh-webservice.de>
svn path=/trunk/yasm/; revision=1330
__YASM_OBJFMT__, use whatever name was specified on the command line. This
also matches the behavior of yasm preprocess-only mode (-e). Both the
mismatch between preproc/non-preproc and the internal name change (e.g. from
elf to elf32) were quite confusing.
Reported by: Mike Frysinger <vapier@gentoo.org>
svn path=/trunk/yasm/; revision=1325
triggered for more cases and optimize from 64-bit down to 32-bit for 64-bit
mov instructions. This change means that mov reg64, constant will be
auto-sized up to 64 bits, but mov reg64, expr/symbol will default to 32 bits.
You must use mov reg64, qword expr/symbol if you need 64 bits, or in GAS
mode use movabsq expr/symbol, reg64.
This makes the generated code smaller and default most usages into 32-bit
relocations appropriate for ELF64 and Win64. Right now, 32-bit unsigned
relocs are generated instead of 32-bit signed; this will need to be fixed.
* x86arch.h (x86_insn.postop): Add X86_POSTOP_SIGNEXT_IMM32.
* x86bc.c (x86_bc_insn_resolve): Implement.
* x86id.re (OPAP_SImm32Avail): New flag.
(MOD_Op2AddSp): New modifier to encode spare directly into 2nd opcode byte.
(arith_insn): Use MOD_Op2AddSp and add forced-size override forms.
(mov_insn): Use OPAP_SImm32Avail and add forced-size override form.
(yasm_x86__finalize_insn): Implement new flag and modifier.
Fix up testcases for changes.
svn path=/trunk/yasm/; revision=1314
up with the alignment as the offset rather than 0. The cause of this was
that elf_sym_set_nonzero was getting a 0 offset which it then did not set.
* elf.c (elf_symtab_set_nonzero): Make value a pointer so that 0 values
can actually get set if necessary.
* elf.h (elf_symtab_set_nonzero): Update prototype.
* elf-objfmt.c (elf_objfmt_symtab_append): Likewise, and ripple changes.
* elf_gas64_reloc.hex: Update (now is correct).
svn path=/trunk/yasm/; revision=1313
GAS output. The way we were generating relocations before would make
common+global symbol usage generate a relocation against the symbol but
figure in the symbol's value into the relocation addend.
* expr.h (yasm_symrec_relocate_action): New enum, so that:
(yasm_expr_extract_symrec): can conditionalize replacing the symbol with its
value based on whether the symbol is only local (e.g. not declared global,
etc).
* expr.c (yasm_expr_extract_symrec): Update implementation.
* xdf-objfmt.c, coff-objfmt.c: Update to use new enum constants.
* elf-objfmt.c (elf_objfmt_output_expr): Only relocate against section if
symbol is only local, and change call to yasm_expr_extract_symrec to only
add in symbol value if symbol is only local.
* stabs-elf.hex, elftest.hex: Update for changes.
* elf_gas64_reloc.asm: New test.
svn path=/trunk/yasm/; revision=1311
* elf.h (elf_symtab_entry): Add in_table flag.
(elf_sym_in_table): New.
* elf.c (elf_symtab_entry_create): Initialize in_table to 0.
(elf_symtab_append_entry, elf_symtab_insert_local_sym): Set flag to 1.
* elf.c (elf_symtab_insert_local_sym): Don't create the entry here, instead
take it as a parameter.
* elf-objfmt.c (elf_objfmt_symtab_append): Only add if not in table by
checking new in_table flag.
(elf_objfmt_append_local_sym): Likewise, and pull some of the logic from
the old elf_symtab_insert_local_sym function to do it.
(elf_objfmt_directive): Don't append to ELF symbol table here, as we don't
know yet if the variable is global or local.
svn path=/trunk/yasm/; revision=1304
time if it already has associated data. This keeps global followed by
extern from generating duplicate symbol table entries.
svn path=/trunk/yasm/; revision=1300
shortening to signed 8-bit immediate from a larger immediate size. This
yields much smaller code for many arithmetic instructions.
Noticed by: Brian Gladman <brg@gladman.plus.com>
svn path=/trunk/yasm/; revision=1227
sections. This breaks section numbering between the file section headers
and the section numbering used by symbols to reference sections.
While we're here, don't even try to number sections during parse... this
numbering is getting overwritten anyway.
Fixes#59 (reported by hkmaly@gmail.com).
svn path=/trunk/yasm/; revision=1226
global symbols in ELF. Search for STV_HIDDEN for explanations; these
don't seem to appear in the base ELF documentation.
Sample syntax:
global foo:hidden
Inspiration and base patch provided by Oskari Saarenmaa under our BSD
license. This checkin tweaks and extends Oskari's patch and adds tests.
svn path=/trunk/yasm/; revision=1202
object formats without creating duplicate lists of symbols. XDF and COFF
were updated; ELF needs to reorder the symbols on its own, so for now it's
not been updated to use the common implementation.
* hamt.c (HAMTEntry, HAMT, HAMT_destroy)
(HAMT_insert): Change SLIST to STAILQ.
* symrec.c (sym_type): Add SYM_SPECIAL.
(yasm_symtab_define_special): New.
(yasm_symrec_declare): New; includes all functionality from symtab_declare.
(yasm_symtab_declare): Call yasm_symrec_declare now.
(yasm_symrec_is_special): New.
* symrec.h: Add prototypes for above.
* xdf-objfmt.c: Use symrec_data instead of declaring xdf_symtab.
* xdflong.hex, xdfprotect.hex, xdfother.hex: Update due to symbol reordering.
* coff-objfmt.c: Use symrec_data instead of declaring coff_symtab.
* elftimes.hex, elfso.hex, elfabssect.hex: Update due to symbol reordering.
* elfglobext.hex, elf-x86id.hex, elftest.hex, elfso64.hex: Likewise.
* stabs-elf.hex: Likewise.
svn path=/trunk/yasm/; revision=1188
similar) to ELF. They are used identically to NASM's ELF shared object
support.
Due to limited WRT support throughout libyasm, this caused a lot of rippling
changes. A major cleanup needs to be performed later to clear some of this
hackiness up.
* elf-machine.h (func_accepts_size_t): Rename to func_accepts_reloc().
(func_map_reloc_info_to_type): Add parameter ssyms for array of special syms.
(elf_machine_ssym): New; for defining machine-specific special syms.
(elf_machine_handler): Change accepts_reloc_size to accepts_reloc. Add new
ssyms and num_ssyms members.
* elf-x86-x86.c (ssym_index): New; this allows nice indexing of ssym arrays.
(elf_x86_x86_accepts_reloc): Rename of elf_x86_x86_accepts_reloc_size. Add
support for various WRT ssyms.
(elf_x86_x86_map_reloc_info_to_type): Add support for various WRT ssyms.
(elf_x86_x86_ssyms): New array of supported special symbols.
(elf_machine_handler_x86_x86): Update for above changes/additions.
* elf-x86-amd64.c (ssym_index, elf_x86_amd64_accepts_reloc)
(elf_x86_amd64_map_reloc_info_to_type, elf_x86_amd64_ssyms)
(elf_machine_handler_x86_amd64): Likewise.
* elf.h (elf_reloc_entry): Add wrt member.
(elf_set_arch): Add symtab parameter.
(elf_is_wrt_sym_relative): New.
(elf_reloc_entry_create): Add wrt parameter.
* elf.c (elf_set_arch): Allocate special syms from machine level.
(elf_is_wrt_sym_relative): New; search special syms, and report whether a
WRT ssym should be symbol-relative or section-relative.
(elf_reloc_entry_create): Pass WRT and ssyms info down to machine level.
* elf-objfmt.c (yasm_objfmt_elf): Add dotdotsym (..sym) symrec member.
(elf_objfmt_create): Pass symtab to elf_set_arch(). Allocate ..sym symbol.
(elf_objfmt_output_reloc): Update for elf_reloc_entry_create() change.
(elf_objfmt_output_expr): Handle WRT ssym. Make relocation symbol-relative
rather than section-relative if either WRT ..sym or WRT ssym that machine
level desires to be symbol-relative.
* symrec.c (yasm_symrec_get_label): Check for NULL sym->value.precbc; this
is now possible due to the user-accessible special symbols that ELF et al
create, which all have NULL precbc's.
* expr.c (yasm_expr_extract_symrec): Recurse into IDENT's to make more exprs
acceptable.
* coretype.h (yasm_output_reloc_func): Remove rel parameter as it shouldn't
be needed and complexifies writing of the reloc functions.
* stabs-dbgfmt.c (stabs_bc_stab_tobytes): Update output_reloc() call.
* elf-objfmt.c (elf_objfmt_output_reloc): Update to match.
* arch.h (yasm_arch_module): Add intnum_fixup_rel() function, change
intnum_tobytes() to not take rel parameter. The rel functionality is being
separated because sometimes it's desirable not to put the data into the
written intnum (e.g. ELF RELA relocations).
(YASM_ARCH_VERSION): Bump due to above change.
(yasm_arch_intnum_fixup_rel): New wrapper.
(yasm_arch_intnum_tobytes): Update wrapper (removing rel).
* lc3bbc.c (yasm_lc3b__intnum_fixup_rel): New, with code from:
(yasm_lc3b__intnum_tobytes): Remove rel code.
* lc3barch.h (yasm_lc3b__intnum_fixup_rel): New.
(yasm_lc3b__intnum_tobytes): Update.
* lc3barch.c (yasm_lc3b_LTX_arch): Reference yasm_lc3b__intnum_fixup_rel().
* x86bc.c (yasm_x86__intnum_fixup_rel): New, with code from:
(yasm_x86__intnum_tobytes): Remove rel code.
* x86arch.h (yasm_x86__intnum_fixup_rel): New.
(yasm_x86__intnum_tobytes): Update.
* x86arch.c (yasm_x86_LTX_arch): Reference yasm_x86__intnum_fixup_rel().
* xdf-objfmt.c (xdf_objfmt_output_expr): Update to use intnum_fixup_rel() /
new intnum_tobytes().
* bin-objfmt.c (bin_objfmt_output_expr): Likewise.
* coff-objfmt.c (coff_objfmt_output_expr): Likewise.
* elf-objfmt.c (elf_objfmt_output_expr: Likewise.
* nasm-listfmt.c (nasm_listfmt_output_expr): Likewise.
* nasm-bison.y: Change precedence of WRT and : operators: instead of being
the strongest binders they are now the weakest. This is needed to correctly
parse and be able to split WRT expressions. WRT handling is still somewhat
of a hack throughout yasm; we'll fix this later.
* x86expr.c (x86_expr_checkea_distcheck_reg): Don't check for WRT here.
(x86_expr_checkea_getregusage): Add new wrt parameter. Use it to handle
"WRT rip" separately from other operators. Recurse if there's a WRT below
the WRT rip; this is to handle cases like ELF-AMD64's elfso64.asm.
(yasm_x86__expr_checkea): Split off top-level WRT's and feed through
separately to x86_expr_checkea_getregusage().
* x86bc.c (x86_bc_insn_tobytes): Ensure the SUB operation for PC-relative
displacements goes BELOW any WRT expression.
(x86_bc_jmp_tobytes): Likewise.
* elfso.asm, elfso.hex, elfso.errwarn: New 32-bit ELF shared object tests.
* modules/objfmts/elf/tests/Makefile.inc: Include in distribution.
* elfso64.asm, elfso64.hex, elfso64.errwarn: New 64-bit ELF shared object
tests. This is not a good example, as the assembled code doesn't work, but
it at least tests the special symbols.
* modules/objfmts/elf/tests/amd64/Makefile.inc: Include in distribution.
svn path=/trunk/yasm/; revision=1168
* elf-x86-x86.c: Add 8-bit and 16-bit relocations (GNU extensions).
* tests/Makefile.inc: Rename elfreloc-err to elfreloc-ext, because relocs
tested in elfreloc-err are now legal due to above changes.
* elfreloc-ext.asm: Likewise.
* elfreloc-ext.errwarn: Likewise.
* elfreloc-ext.hex: New output file.
svn path=/trunk/yasm/; revision=1161
should use .rela.* instead of .rel.* sections, of type SHT_RELA instead
of SHT_REL.
* elf.h, elf.c: update calls to backend, passing relocations further in.
* elf-machine.h, elf-x86-amd64.c, elf-x86-x86.c: add support for setting
relocation section name, type, and update amd64 to write RELA records.
Also when creating a relocation and writing a value to the file, have
it handled here to keep REL vs RELA distinctions hidden from elf.c.
* elf-rip.hex: update output to match new section type and data output.
svn path=/trunk/yasm/; revision=1160
preventing a segfault. The assumptions it had made for all sections
were wrong with absolute sections, so added just as much special casing
as necessary. I hope the output is correct as well - this way we should
at least get bugs if it's wrong.
Reported by: Ben Skeggs <d4rk74m4@intas.net.au>
svn path=/trunk/yasm/; revision=1119
[rip+symbol] in that the latter adds the symbol offset to rip, whereas the
former is the same as [symbol] but uses rip-relative addressing. This is
a minor overload of the WRT operator, but reads well and shouldn't conflict
with the use of WRT against sections.
Doing this currently adds a bit of overhead to all effective addresses in
64-bit mode (a $ symbol reference). This is the cleanest approach I could
figure out; a time/space trade could be made later, such as prescanning for
RIP usage before allocating the symbol.
svn path=/trunk/yasm/; revision=1032
Add elf x86 test case to verify it works properly.
Unsure about elf x86-64 status (relocations segfault my objdump), but
it's no *worse* than last commit.
svn path=/trunk/yasm/; revision=1029
another test such that linked together they verify that
1. It links properly
2. The constant is loaded properly
3. The function is called properly
shown (probably not proved) by the program exiting with error level 0.
svn path=/trunk/yasm/; revision=1024