summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2016-02-16 17:38:58 -0800
committerH. Peter Anvin <hpa@linux.intel.com>2016-02-16 17:38:58 -0800
commitec62791d8c815cdeaf9fe0889787111d58e3535e (patch)
tree247ae44ff5dd9b81f5f089c00006f6712b51ad7d
parent2c4a4d5810d0a59b033a07876a2648ef5d4c2859 (diff)
downloadnasm-ec62791d8c815cdeaf9fe0889787111d58e3535e.tar.gz
outmacho: sanitize the handling of sections
Sanitize the handling of sections in outmacho somewhat. This should bring further performance improvements. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--output/outmacho.c48
1 files changed, 18 insertions, 30 deletions
diff --git a/output/outmacho.c b/output/outmacho.c
index 6872a7bf..24b43386 100644
--- a/output/outmacho.c
+++ b/output/outmacho.c
@@ -112,6 +112,7 @@ struct section {
struct section *next;
struct SAA *data;
int32_t index;
+ int32_t fileindex;
struct reloc *relocs;
int align;
bool by_name; /* This section was specified by full MachO name */
@@ -291,14 +292,9 @@ static struct section *get_section_by_index(const int32_t index)
static uint8_t get_section_fileindex_by_index(const int32_t index)
{
- struct section *s;
- uint8_t i = 1;
-
- for (s = sects; s != NULL; s = s->next, ++i)
- if (index == s->index)
- return i;
+ struct section *s = get_section_by_index(index);
- return NO_SECT;
+ return s ? s->fileindex : NO_SECT;
}
/*
@@ -426,13 +422,13 @@ static int64_t add_reloc(struct section *sect, int32_t section,
case RL_GOT:
r->pcrel = 1;
r->type = 4; // X86_64_RELOC_GOT
- r->snum = macho_gotpcrel_sect;
+ r->snum = macho_gotpcrel_sect; /* WTF? */
break;
case RL_GOTLOAD:
r->pcrel = 1;
r->type = 3; // X86_64_RELOC_GOT_LOAD
- r->snum = macho_gotpcrel_sect;
+ r->snum = macho_gotpcrel_sect; /* WTF? */
break;
}
@@ -596,7 +592,6 @@ static void macho_output(int32_t secto, const void *data,
static int32_t macho_section(char *name, int pass, int *bits)
{
- int32_t index;
char *sectionAttributes;
struct sectmap *sm;
struct section *s;
@@ -657,6 +652,7 @@ static int32_t macho_section(char *name, int pass, int *bits)
if (!strcmp(name, sm->nasmsect)) {
segment = sm->segname;
section = sm->sectname;
+ flags = sm->flags;
goto found;
}
}
@@ -678,6 +674,7 @@ static int32_t macho_section(char *name, int pass, int *bits)
s->data = saa_init(1L);
s->index = seg_alloc();
+ s->fileindex = ++seg_nsects;
s->relocs = NULL;
s->align = -1;
s->pad = -1;
@@ -689,8 +686,6 @@ static int32_t macho_section(char *name, int pass, int *bits)
s->size = 0;
s->nreloc = 0;
s->flags = flags;
-
- index = s->index;
} else {
new_seg = false;
}
@@ -713,19 +708,17 @@ static int32_t macho_section(char *name, int pass, int *bits)
newAlignment = alignlog2_32(value);
if (0 != *end) {
- nasm_error(ERR_FATAL,
+ nasm_error(ERR_NONFATAL,
"unknown or missing alignment value \"%s\" "
"specified for section \"%s\"",
currentAttribute + 6,
name);
- return NO_SEG;
} else if (0 > newAlignment) {
- nasm_error(ERR_FATAL,
+ nasm_error(ERR_NONFATAL,
"alignment of %d (for section \"%s\") is not "
"a power of two",
value,
name);
- return NO_SEG;
}
if (s->align < newAlignment)
@@ -758,7 +751,7 @@ static int32_t macho_section(char *name, int pass, int *bits)
}
}
- return index;
+ return s->index;
}
static void macho_symdef(char *name, int32_t section, int64_t offset,
@@ -803,7 +796,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
/* external and common symbols get N_EXT */
if (is_global != 0) {
sym->type |= N_EXT;
- }
+ }
if (section == NO_SEG) {
/* symbols in no section get absolute */
@@ -815,16 +808,15 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
/* get the in-file index of the section the symbol was defined in */
sym->sect = get_section_fileindex_by_index(section);
- /* track the initially allocated symbol number for use in future fix-ups */
- sym->initial_snum = nsyms;
+ /* track the initially allocated symbol number for use in future fix-ups */
+ sym->initial_snum = nsyms;
if (sym->sect == NO_SECT) {
-
/* remember symbol number of references to external
** symbols, this works because every external symbol gets
** its own section number allocated internally by nasm and
** can so be used as a key */
- extsyms = raa_write(extsyms, section, nsyms);
+ extsyms = raa_write(extsyms, section, nsyms);
switch (is_global) {
case 1:
@@ -839,8 +831,7 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
/* give an error on unfound section if it's not an
** external or common symbol (assemble_file() does a
** seg_alloc() on every call for them) */
- nasm_error(ERR_PANIC, "in-file index for section %d not found",
- section);
+ nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
}
}
}
@@ -852,10 +843,9 @@ static void macho_sectalign(int32_t seg, unsigned int value)
struct section *s;
int align;
- list_for_each(s, sects) {
- if (s->index == seg)
- break;
- }
+ nasm_assert(!(seg & 1));
+
+ s = get_section_by_index(seg);
if (!s || !is_power2(value))
return;
@@ -1016,8 +1006,6 @@ static void macho_calculate_sizes (void)
s->offset = seg_filesize + s->pad;
seg_filesize += s->size + s->pad;
}
-
- ++seg_nsects;
}
/* calculate size of all headers, load commands and sections to