Linking with assembly code

The Hare build driver will automatically assemble and link with assembly sources included in a module directory with the file extension .s. However, some special considerations are worth addressing with respect to assembly users.

Namespaces & symbols

The build process will not automatically place your assembly symbols in the namespace corresponding with the module in which they appear.

On ELF targets, Hare identifiers are translated into symbol names by replacing each namespace separator (::) with a dot (.), such that hash::fnv::fnv64 becomes hash.fnv.fnv64. To make your assembly symbols appear correctly in their module, you must prefix them with the namespace in the dotted notation.

You may also want to add a corresponding forward declaration to your Hare source so globals defined in assembly appear to the Hare compiler. For example:

x86_64/rdtsc.s
.global x86_64.rdtsc
x86_64.rdtsc:
     xorq %rax, %rax
     rdtsc
     shl $32, %rdx
     orq %rdx, %rax
     ret
x86_64/native.ha
// Returns the current value of the tsc register.
export fn rdtsc() u64;

This will cause x86_64::rdtsc to be visible to Hare programs importing the x86_64 module.

Assembled as one unit

Assembly sources are passed to the assembler in one go, such that a module with a.s and b.s will be compiled with a single as a.s b.s command. The same assembler invocation will also include all of the compiled Hare sources. With many assemblers (including the GNU binutils assembler), the input files are essentially concatenated, preserving some state between files. As such, you should begin each file with the segment it belongs in, using directives like .text or .bss.

Unused symbol pruning

Hare instructs the linker to prune unused symbols to reduce binary sizes. In order to do this, each symbol must be in its own ELF section. If you want your assembly code to be pruned when unused in practice, add .section .text.$symname or similar rather than using .text et al as shorthand.

Application binary interface

Hare’s ABI is generally a superset of the C ABI for the target. These are defined in the following specifications:

Consult the Hare specification for representations of Hare-exclusive constructs, such as tagged unions or tuples.