mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-03-31 18:20:22 +08:00
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.
This commit is contained in:
parent
5547e191fe
commit
5eb2d2b094
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user