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:
H. Peter Anvin 2017-06-23 14:48:08 -07:00
commit aac369d5b0
7 changed files with 140 additions and 37 deletions

View file

@ -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
View 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

View file

@ -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 {

View file

@ -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)
{

View file

@ -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:

View file

@ -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)

View file

@ -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 - $$