diff options
author | Eric Christopher <echristo@apple.com> | 2005-12-09 00:27:26 +0000 |
---|---|---|
committer | Eric Christopher <echristo@apple.com> | 2005-12-09 00:27:26 +0000 |
commit | 5eb2d2b09426fe9518afe641a6a783498b8e52b4 (patch) | |
tree | 499f12f02ac3544480d2864e4e3650e63fb555e2 /output | |
parent | 5547e191fe69992b57fc6b7d948a20bd06fd5bf3 (diff) | |
download | nasm-5eb2d2b09426fe9518afe641a6a783498b8e52b4.tar.gz nasm-5eb2d2b09426fe9518afe641a6a783498b8e52b4.tar.bz2 nasm-5eb2d2b09426fe9518afe641a6a783498b8e52b4.zip |
2005-12-08 Wade Tregaskis <wtregaskis@apple.com>
* nasm/nasm/output/outmacho.c (struct section): Added "align" field.
(sectmap): Added ".rodata" section.
(exact_log2): New.
(macho_section): Added support for section attributes.
"align=" and "data" specifically.
(macho_write_segment): Write out section alignment to Mach-O file.
Diffstat (limited to 'output')
-rw-r--r-- | output/outmacho.c | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/output/outmacho.c b/output/outmacho.c index ab5713f..e3603b7 100644 --- a/output/outmacho.c +++ b/output/outmacho.c @@ -52,6 +52,7 @@ struct section { struct SAA *data; long index; struct reloc *relocs; + int align; /* data that goes into the file */ char sectname[16]; /* what this section is called */ @@ -83,6 +84,7 @@ static struct sectmap { } sectmap[] = { { ".text", "__TEXT", "__text", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS}, { ".data", "__DATA", "__data", S_REGULAR}, { +".rodata", "__DATA", "__const", S_REGULAR}, { ".bss", "__DATA", "__bss", S_ZEROFILL}, { NULL, NULL, NULL}}; @@ -131,6 +133,8 @@ struct symbol { #define N_TYPE 0x0e /* type bit mask */ +#define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */ + /* special section number values */ #define NO_SECT 0 /* no section, invalid */ #define MAX_SECT 255 /* maximum number of sections */ @@ -196,6 +200,24 @@ unsigned long rel_padcnt = 0; static void debug_reloc (struct reloc *); static void debug_section_relocs (struct section *) __attribute__ ((unused)); +static int exact_log2 (unsigned long align) { + if (align != (align & -align)) { + return -1; + } else { +#ifdef __GNUC__ + return (align ? __builtin_ctzl (align) : 0); +#else + unsigned long result = 0; + + while (align >>= 1) { + ++result; + } + + return result; +#endif + } +} + static struct section *get_section_by_name(const char *segname, const char *sectname) { @@ -484,22 +506,29 @@ static void macho_output(long secto, const void *data, unsigned long type, static long macho_section(char *name, int pass, int *bits) { - long index; + long index, originalIndex; + char *sectionAttributes; struct sectmap *sm; struct section *s; /* Default to 32 bits. */ - if (!name) + if (!name) { *bits = 32; - - if (!name) name = ".text"; + sectionAttributes = NULL; + } else { + sectionAttributes = name; + name = strsep(§ionAttributes, " \t"); + } for (sm = sectmap; sm->nasmsect != NULL; ++sm) { /* make lookup into section name translation table */ if (!strcmp(name, sm->nasmsect)) { + char *currentAttribute; + /* try to find section with that name */ - index = get_section_index_by_name(sm->segname, sm->sectname); + originalIndex = index = get_section_index_by_name(sm->segname, + sm->sectname); /* create it if it doesn't exist yet */ if (index == -1) { @@ -510,6 +539,7 @@ static long macho_section(char *name, int pass, int *bits) s->data = saa_init(1L); s->index = seg_alloc(); s->relocs = NULL; + s->align = DEFAULT_SECTION_ALIGNMENT; xstrncpy(s->segname, sm->segname); xstrncpy(s->sectname, sm->sectname); @@ -518,6 +548,59 @@ static long macho_section(char *name, int pass, int *bits) s->flags = sm->flags; index = s->index; + } else { + s = get_section_by_index(index); + } + + while ((NULL != sectionAttributes) + && (currentAttribute = strsep(§ionAttributes, " \t"))) { + if (0 != *currentAttribute) { + if (0 == strncasecmp("align=", currentAttribute, 6)) { + char *end; + int newAlignment, value; + + value = strtoul(currentAttribute + 6, &end, 0); + newAlignment = exact_log2(value); + + if (0 != *end) { + error(ERR_PANIC, + "unknown or missing alignment value \"%s\" " + "specified for section \"%s\"", + currentAttribute + 6, + name); + return NO_SEG; + } else if (0 > newAlignment) { + error(ERR_PANIC, + "alignment of %d (for section \"%s\") is not " + "a power of two", + value, + name); + return NO_SEG; + } + + if ((-1 != originalIndex) + && (s->align != newAlignment)) { + error(ERR_PANIC, + "section \"%s\" has already been specified " + "with alignment %d, conflicts with new " + "alignment of %d", + name, + (1 << s->align), + value); + return NO_SEG; + } + + s->align = newAlignment; + } else if (0 == strcasecmp("data", currentAttribute)) { + /* Do nothing; 'data' is implicit */ + } else { + error(ERR_PANIC, + "unknown section attribute %s for section %s", + currentAttribute, + name); + return NO_SEG; + } + } } return index; @@ -804,7 +887,9 @@ static unsigned long macho_write_segment (unsigned long offset) /* dummy data for zerofill sections or proper values */ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) { fwritelong(offset, machofp); - fwritelong(0, machofp); + /* Write out section alignment, as a power of two. + e.g. 32-bit word alignment would be 2 (2^^2 = 4). */ + fwritelong(s->align, machofp); /* To be compatible with cctools as we emit a zero reloff if we have no relocations. */ fwritelong(s->nreloc ? rel_base + s_reloff : 0, machofp); |