mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-21 03:14:19 +08:00
Merge remote-tracking branch 'origin/nasm-2.13.xx'
Resolved Conflicts: common/common.c Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
commit
aac369d5b0
@ -24,6 +24,9 @@ The Makefiles are:
|
||||
5. The Perl module Font::TTF (can usually be installed
|
||||
via the "CPAN Client" in your Perl distribution)
|
||||
http://search.cpan.org/~bhallissy/Font-TTF/
|
||||
6. The Perl module Sort::Versions (can usually be installed
|
||||
via the "CPAN Client" in your Perl distribution)
|
||||
http://search.cpan.org/~neilb/Sort-Versions-1.62/lib/Sort/Versions.pm
|
||||
|
||||
The tools need to be in your current path. To build the
|
||||
installer package, run:
|
||||
|
20
doc/README
Normal file
20
doc/README
Normal file
@ -0,0 +1,20 @@
|
||||
To build the entire documentation, the following tools are needed:
|
||||
|
||||
1. A Perl interpreter for your platform
|
||||
2. The following Perl modules available from CPAN:
|
||||
Font::TTF
|
||||
Sort::Versions
|
||||
3. asciidoc
|
||||
http://asciidoc.org/
|
||||
4. xmlto
|
||||
https://fedorahosted.org/xmlto
|
||||
5. One of:
|
||||
Adobe Acrobat (acrodist)
|
||||
Ghostscript (ps2pdf) http://download.ghostscript.com/
|
||||
pstopdf (available on some BSD-derived Unix systems)
|
||||
|
||||
Of these, Ghostscript is the most tested, although Acrobat has
|
||||
been claimed to generate smaller files.
|
||||
6. For best results, the Adobe fonts Source Sans Pro and Source Code
|
||||
Pro, available for free at:
|
||||
https://github.com/adobe-fonts
|
@ -61,6 +61,16 @@ ul.index {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
@media only screen {
|
||||
div.contents {
|
||||
-webkit-column-gap: 4em;
|
||||
-webkit-column-rule: 1px dotted black;
|
||||
-moz-column-gap: 4em;
|
||||
-moz-column-rule: 1px dotted black;
|
||||
column-gap: 4em;
|
||||
column-rule: 1px dotted black;
|
||||
}
|
||||
}
|
||||
@media only screen and (min-width: 90em) {
|
||||
/* For a very wide screen, go to a columnar layout */
|
||||
div.contents {
|
||||
|
@ -299,7 +299,7 @@ void saa_write8(struct SAA *s, uint8_t v)
|
||||
saa_wbytes(s, &v, 1);
|
||||
}
|
||||
|
||||
#ifdef WORDS_LITTEENDIAN
|
||||
#ifdef WORDS_LITTLEENDIAN
|
||||
|
||||
void saa_write16(struct SAA *s, uint16_t v)
|
||||
{
|
||||
|
@ -194,7 +194,7 @@ static void dbg_out(const struct out_data *data)
|
||||
fprintf(ofile, " wrt %"PRIx32, data->twrt);
|
||||
}
|
||||
if (data->type == OUT_RELADDR)
|
||||
fprintf(ofile, " relbase %"PRId64, data->relbase);
|
||||
fprintf(ofile, " relbase %"PRIx64, data->relbase);
|
||||
|
||||
putc('\n', ofile);
|
||||
|
||||
@ -248,8 +248,8 @@ static void dbg_legacy_out(int32_t segto, const void *data,
|
||||
fprintf(ofile, " legacy: out to %"PRIx32", len = %d: ",
|
||||
segto, (int)abs((int)size));
|
||||
else
|
||||
fprintf(ofile, " legacy: out to %"PRIx32", len = %"PRIu64": ",
|
||||
segto, size);
|
||||
fprintf(ofile, " legacy: out to %"PRIx32", len = %"PRId64" (0x%"PRIx64"): ",
|
||||
segto, (int64_t)size, size);
|
||||
|
||||
switch (type) {
|
||||
case OUT_RESERVE:
|
||||
|
@ -138,6 +138,7 @@ struct macho_fmt {
|
||||
uint32_t reloc_abs; /* Absolute relocation type */
|
||||
uint32_t reloc_rel; /* Relative relocation type */
|
||||
uint32_t reloc_tlv; /* Thread local relocation type */
|
||||
bool forcesym; /* Always use "external" (symbol-relative) relocations */
|
||||
};
|
||||
|
||||
static struct macho_fmt fmt;
|
||||
@ -154,7 +155,7 @@ struct section {
|
||||
int32_t index;
|
||||
int32_t fileindex;
|
||||
struct reloc *relocs;
|
||||
struct rbtree *gsyms; /* Global symbols in section */
|
||||
struct rbtree *syms[2]; /* All/global symbols symbols in section */
|
||||
int align;
|
||||
bool by_name; /* This section was specified by full MachO name */
|
||||
|
||||
@ -215,7 +216,7 @@ struct reloc {
|
||||
|
||||
struct symbol {
|
||||
/* nasm internal data */
|
||||
struct rbtree symv; /* Global symbol rbtree; "key" contains the
|
||||
struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
|
||||
symbol offset. */
|
||||
struct symbol *next; /* next symbol in the list */
|
||||
char *name; /* name of this symbol */
|
||||
@ -412,21 +413,22 @@ static void sect_write(struct section *sect,
|
||||
/*
|
||||
* Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
|
||||
*/
|
||||
static struct symbol *macho_find_gsym(struct section *s,
|
||||
uint64_t offset, bool exact)
|
||||
static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
|
||||
bool global, bool exact)
|
||||
{
|
||||
struct rbtree *srb;
|
||||
|
||||
srb = rb_search(s->gsyms, offset);
|
||||
srb = rb_search(s->syms[global], offset);
|
||||
|
||||
if (!srb || (exact && srb->key != offset)) {
|
||||
nasm_error(ERR_NONFATAL, "unable to find a suitable %s symbol"
|
||||
nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
|
||||
" for this reference",
|
||||
s == &absolute_sect ? "absolute" : "global");
|
||||
global ? " global" : "",
|
||||
s == &absolute_sect ? " absolute " : "");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return container_of(srb, struct symbol, symv);
|
||||
return container_of(srb - global, struct symbol, symv);
|
||||
}
|
||||
|
||||
static int64_t add_reloc(struct section *sect, int32_t section,
|
||||
@ -469,7 +471,7 @@ static int64_t add_reloc(struct section *sect, int32_t section,
|
||||
if (section == NO_SEG) {
|
||||
/* absolute (can this even happen?) */
|
||||
r->ext = 0;
|
||||
r->snum = R_ABS;
|
||||
r->snum = NO_SECT;
|
||||
} else if (fi == NO_SECT) {
|
||||
/* external */
|
||||
r->snum = raa_read(extsyms, section);
|
||||
@ -493,8 +495,8 @@ static int64_t add_reloc(struct section *sect, int32_t section,
|
||||
#if 0
|
||||
/* This "seems" to be how it ought to work... */
|
||||
|
||||
struct symbol *sym = macho_find_gsym(&absolute_sect,
|
||||
offset, false);
|
||||
struct symbol *sym = macho_find_sym(&absolute_sect, offset,
|
||||
false, false);
|
||||
if (!sym)
|
||||
goto bail;
|
||||
|
||||
@ -543,15 +545,27 @@ static int64_t add_reloc(struct section *sect, int32_t section,
|
||||
/* external */
|
||||
r->snum = raa_read(extsyms, section);
|
||||
} else {
|
||||
/* internal */
|
||||
struct symbol *sym = macho_find_gsym(s, offset, reltype != RL_TLV);
|
||||
/* internal - does it really need to be global? */
|
||||
struct symbol *sym = macho_find_sym(s, offset, true,
|
||||
reltype != RL_TLV);
|
||||
if (!sym)
|
||||
goto bail;
|
||||
|
||||
r->snum = sym->initial_snum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* For 64-bit Mach-O, force a symbol reference if at all possible */
|
||||
if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
|
||||
struct symbol *sym = macho_find_sym(s, offset, false, false);
|
||||
if (sym) {
|
||||
adjust = bytes - sym->symv[0].key;
|
||||
r->snum = sym->initial_snum;
|
||||
r->ext = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* NeXT as puts relocs in reversed order (address-wise) into the
|
||||
** files, so we do the same, doesn't seem to make much of a
|
||||
** difference either way */
|
||||
@ -645,7 +659,7 @@ static void macho_output(int32_t secto, const void *data,
|
||||
if (section != NO_SEG) {
|
||||
if (section % 2) {
|
||||
nasm_error(ERR_NONFATAL, "Mach-O format does not support"
|
||||
" section base references");
|
||||
" section base references");
|
||||
} else if (wrt == NO_SEG) {
|
||||
if (fmt.ptrsize == 8 && asize != 8) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
@ -968,6 +982,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
int is_global, char *special)
|
||||
{
|
||||
struct symbol *sym;
|
||||
struct section *s;
|
||||
|
||||
if (special) {
|
||||
nasm_error(ERR_NONFATAL, "The Mach-O output format does "
|
||||
@ -1000,7 +1015,8 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
sym->strx = strslen;
|
||||
sym->type = 0;
|
||||
sym->desc = 0;
|
||||
sym->symv.key = offset;
|
||||
sym->symv[0].key = offset;
|
||||
sym->symv[1].key = offset;
|
||||
sym->initial_snum = -1;
|
||||
|
||||
/* external and common symbols get N_EXT */
|
||||
@ -1013,10 +1029,9 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
sym->type |= N_ABS;
|
||||
sym->sect = NO_SECT;
|
||||
|
||||
/* all absolute symbols are available to use as references */
|
||||
absolute_sect.gsyms = rb_insert(absolute_sect.gsyms, &sym->symv);
|
||||
s = &absolute_sect;
|
||||
} else {
|
||||
struct section *s = get_section_by_index(section);
|
||||
s = get_section_by_index(section);
|
||||
|
||||
sym->type |= N_SECT;
|
||||
|
||||
@ -1038,7 +1053,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
case 2:
|
||||
/* there isn't actually a difference between global
|
||||
** and common symbols, both even have their size in
|
||||
** sym->symv.key */
|
||||
** sym->symv[0].key */
|
||||
sym->type = N_EXT;
|
||||
break;
|
||||
|
||||
@ -1049,10 +1064,15 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
|
||||
break;
|
||||
}
|
||||
} else if (is_global) {
|
||||
s->gsyms = rb_insert(s->gsyms, &sym->symv);
|
||||
}
|
||||
}
|
||||
|
||||
if (s) {
|
||||
s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
|
||||
if (is_global)
|
||||
s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
|
||||
}
|
||||
|
||||
++nsyms;
|
||||
}
|
||||
|
||||
@ -1467,10 +1487,10 @@ static void macho_write_symtab (void)
|
||||
sizes. */
|
||||
if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
|
||||
nasm_assert(sym->sect <= seg_nsects);
|
||||
sym->symv.key += sectstab[sym->sect]->addr;
|
||||
sym->symv[0].key += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
|
||||
fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
}
|
||||
|
||||
@ -1485,10 +1505,10 @@ static void macho_write_symtab (void)
|
||||
sizes. */
|
||||
if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
|
||||
nasm_assert(sym->sect <= seg_nsects);
|
||||
sym->symv.key += sectstab[sym->sect]->addr;
|
||||
sym->symv[0].key += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
|
||||
fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
|
||||
for (i = 0; i < nundefsym; i++) {
|
||||
@ -1502,10 +1522,10 @@ static void macho_write_symtab (void)
|
||||
sizes. */
|
||||
if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
|
||||
nasm_assert(sym->sect <= seg_nsects);
|
||||
sym->symv.key += sectstab[sym->sect]->addr;
|
||||
sym->symv[0].key += sectstab[sym->sect]->addr;
|
||||
}
|
||||
|
||||
fwriteptr(sym->symv.key, ofile); /* value (i.e. offset) */
|
||||
fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
|
||||
}
|
||||
|
||||
}
|
||||
@ -2232,7 +2252,8 @@ static const struct macho_fmt macho32_fmt = {
|
||||
RL_MAX_32,
|
||||
GENERIC_RELOC_VANILLA,
|
||||
GENERIC_RELOC_VANILLA,
|
||||
GENERIC_RELOC_TLV
|
||||
GENERIC_RELOC_TLV,
|
||||
false /* Allow segment-relative relocations */
|
||||
};
|
||||
|
||||
static void macho32_init(void)
|
||||
@ -2277,7 +2298,7 @@ const struct ofmt of_macho32 = {
|
||||
null_directive,
|
||||
macho_filename,
|
||||
macho_cleanup,
|
||||
macho_pragma_list,
|
||||
macho_pragma_list
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -2294,7 +2315,8 @@ static const struct macho_fmt macho64_fmt = {
|
||||
RL_MAX_64,
|
||||
X86_64_RELOC_UNSIGNED,
|
||||
X86_64_RELOC_SIGNED,
|
||||
X86_64_RELOC_TLV
|
||||
X86_64_RELOC_TLV,
|
||||
true /* Force symbol-relative relocations */
|
||||
};
|
||||
|
||||
static void macho64_init(void)
|
||||
|
@ -1,9 +1,57 @@
|
||||
bits 64
|
||||
default rel
|
||||
|
||||
%if 1
|
||||
extern bar
|
||||
%else
|
||||
section .bss
|
||||
bar: resd 0
|
||||
%endif
|
||||
|
||||
global start
|
||||
global foo
|
||||
|
||||
section .rodata
|
||||
rod1: dd 0x01234567
|
||||
rod2: dd 0x89abcdef
|
||||
|
||||
section .text
|
||||
start:
|
||||
call .next
|
||||
.next: pop rsi
|
||||
sub rsi,.next-$$
|
||||
|
||||
lea rax, [rod1]
|
||||
lea rcx, [rod2]
|
||||
lea rdx, [bar]
|
||||
lea rbx, [foo]
|
||||
|
||||
lea rax, [rdi+rod1-$$]
|
||||
lea rcx, [rdi+rod2-$$]
|
||||
lea rdx, [rdi+bar-$$]
|
||||
lea rbx, [rdi+foo-$$]
|
||||
|
||||
mov rax, [rdi+rod1-$$]
|
||||
mov rcx, [rdi+rod2-$$]
|
||||
mov rdx, [rdi+bar-$$]
|
||||
mov rbx, [rdi+foo-$$]
|
||||
|
||||
mov rax, dword rod1-$$
|
||||
mov rcx, dword rod2-$$
|
||||
mov rdx, dword bar-$$
|
||||
mov rbx, dword foo-$$
|
||||
|
||||
section .data
|
||||
foo: dd bar
|
||||
dd foo - $
|
||||
; dd foo*2
|
||||
dq rod1
|
||||
dq rod2
|
||||
dq bar
|
||||
dq foo
|
||||
foo:
|
||||
dd rod1 - $
|
||||
dd rod1 - $$
|
||||
dd rod2 - $
|
||||
dd rod2 - $$
|
||||
dd bar - $
|
||||
dd bar - $$
|
||||
dd foo - $
|
||||
dd foo - $$
|
||||
|
Loading…
Reference in New Issue
Block a user