mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-02-23 17:29:23 +08:00
Add support for backend-defined subsections and label hacks
MachO has this odd thing called "subsections via symbols", by which a symbol can magically start what effectively is a new section. To support this, add support for a calldown into the backend when a new symbol is defined *at the current output location*, and allow it to switch the current segment. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
parent
b7136487bd
commit
892c4818ce
@ -251,9 +251,8 @@ bool process_directives(char *directive)
|
||||
nasm_error(pass0 < 2 ? ERR_NONFATAL : ERR_PANIC,
|
||||
"segment name `%s' not recognized", value);
|
||||
} else {
|
||||
in_absolute = false;
|
||||
location.segment = seg;
|
||||
globalbits = sb;
|
||||
switch_segment(seg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
33
asm/labels.c
33
asm/labels.c
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -231,6 +231,32 @@ bool is_extern(const char *label)
|
||||
return (lptr && (lptr->defn.is_global & EXTERN_BIT));
|
||||
}
|
||||
|
||||
static void handle_herelabel(const char *label,
|
||||
int32_t *segment, int64_t *offset)
|
||||
{
|
||||
int32_t oldseg;
|
||||
|
||||
if (likely(!ofmt->herelabel))
|
||||
return;
|
||||
|
||||
if (unlikely(location.segment == NO_SEG))
|
||||
return;
|
||||
|
||||
oldseg = *segment;
|
||||
|
||||
if (oldseg == location.segment && *offset == location.offset) {
|
||||
/* This label is defined at this location */
|
||||
int32_t newseg;
|
||||
|
||||
newseg = ofmt->herelabel(label, oldseg);
|
||||
if (likely(newseg == oldseg))
|
||||
return;
|
||||
|
||||
*segment = newseg;
|
||||
*offset = switch_segment(newseg);
|
||||
}
|
||||
}
|
||||
|
||||
void redefine_label(char *label, int32_t segment, int64_t offset, char *special,
|
||||
bool is_norm, bool isextrn)
|
||||
{
|
||||
@ -254,6 +280,8 @@ void redefine_label(char *label, int32_t segment, int64_t offset, char *special,
|
||||
label, segment, offset, special, is_norm, isextrn);
|
||||
#endif
|
||||
|
||||
handle_herelabel(label, &segment, &offset);
|
||||
|
||||
lptr = find_label(label, 1, &created);
|
||||
if (!lptr)
|
||||
nasm_panic(0, "can't find label `%s' on pass two", label);
|
||||
@ -310,6 +338,9 @@ void define_label(char *label, int32_t segment, int64_t offset, char *special,
|
||||
nasm_error(ERR_DEBUG, "define_label (%s, %"PRIx32", %"PRIx64", %s, %d, %d)",
|
||||
label, segment, offset, special, is_norm, isextrn);
|
||||
#endif
|
||||
|
||||
handle_herelabel(label, &segment, &offset);
|
||||
|
||||
lptr = find_label(label, 1, NULL);
|
||||
if (!lptr)
|
||||
return;
|
||||
|
46
asm/nasm.c
46
asm/nasm.c
@ -153,9 +153,17 @@ static char *quote_for_pmake(const char *str);
|
||||
static char *quote_for_wmake(const char *str);
|
||||
static char *(*quote_for_make)(const char *) = quote_for_pmake;
|
||||
|
||||
static int64_t get_curr_offs(void)
|
||||
int64_t switch_segment(int32_t segment)
|
||||
{
|
||||
return in_absolute ? absolute.offset : raa_read(offsets, location.segment);
|
||||
location.segment = segment;
|
||||
if (segment == NO_SEG) {
|
||||
location.offset = absolute.offset;
|
||||
in_absolute = true;
|
||||
} else {
|
||||
location.offset = raa_read(offsets, segment);
|
||||
in_absolute = false;
|
||||
}
|
||||
return location.offset;
|
||||
}
|
||||
|
||||
static void set_curr_offs(int64_t l_off)
|
||||
@ -166,6 +174,15 @@ static void set_curr_offs(int64_t l_off)
|
||||
offsets = raa_write(offsets, location.segment, l_off);
|
||||
}
|
||||
|
||||
static void increment_offset(int64_t delta)
|
||||
{
|
||||
if (unlikely(delta == 0))
|
||||
return;
|
||||
|
||||
location.offset += delta;
|
||||
set_curr_offs(location.offset);
|
||||
}
|
||||
|
||||
static void nasm_fputs(const char *line, FILE * outfile)
|
||||
{
|
||||
if (outfile) {
|
||||
@ -1285,7 +1302,6 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
char *line;
|
||||
insn output_ins;
|
||||
int i;
|
||||
int64_t offs;
|
||||
int pass_max;
|
||||
uint64_t prev_offset_changed;
|
||||
unsigned int stall_count = 0; /* Make sure we make forward progress... */
|
||||
@ -1326,22 +1342,25 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
}
|
||||
in_absolute = false;
|
||||
global_offset_changed = 0; /* set by redefine_label */
|
||||
location.segment = ofmt->section(NULL, pass2, &globalbits);
|
||||
seg_alloc_reset();
|
||||
if (passn > 1) {
|
||||
saa_rewind(forwrefs);
|
||||
forwref = saa_rstruct(forwrefs);
|
||||
raa_free(offsets);
|
||||
offsets = raa_init();
|
||||
}
|
||||
location.segment = NO_SEG;
|
||||
location.offset = 0;
|
||||
if (passn == 1)
|
||||
location.known = true;
|
||||
ofmt->reset();
|
||||
switch_segment(ofmt->section(NULL, pass2, &globalbits));
|
||||
preproc->reset(fname, pass1, pass1 == 2 ? depend_ptr : NULL);
|
||||
|
||||
/* Revert all warnings to the default state */
|
||||
memcpy(warning_state, warning_state_init, sizeof warning_state);
|
||||
|
||||
globallineno = 0;
|
||||
if (passn == 1)
|
||||
location.known = true;
|
||||
location.offset = offs = get_curr_offs();
|
||||
|
||||
while ((line = preproc->getline())) {
|
||||
if (globallineno++ == GLOBALLINENO_MAX)
|
||||
@ -1459,7 +1478,8 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
|
||||
for (n = 1; n <= output_ins.times; n++) {
|
||||
if (pass1 == 1) {
|
||||
int64_t l = insn_size(location.segment, offs,
|
||||
int64_t l = insn_size(location.segment,
|
||||
location.offset,
|
||||
globalbits, &output_ins);
|
||||
|
||||
/* if (using_debug_info) && output_ins.opcode != -1) */
|
||||
@ -1542,8 +1562,7 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
* input file over and over.
|
||||
*/
|
||||
if (l != -1) {
|
||||
offs += l;
|
||||
set_curr_offs(offs);
|
||||
increment_offset(l);
|
||||
}
|
||||
/*
|
||||
* else l == -1 => invalid instruction, which will be
|
||||
@ -1552,9 +1571,9 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
} else {
|
||||
if (n == 2)
|
||||
lfmt->uplevel(LIST_TIMES);
|
||||
offs += assemble(location.segment, offs,
|
||||
globalbits, &output_ins);
|
||||
set_curr_offs(offs);
|
||||
increment_offset(assemble(location.segment,
|
||||
location.offset,
|
||||
globalbits, &output_ins));
|
||||
}
|
||||
} /* not an EQU */
|
||||
}
|
||||
@ -1565,7 +1584,6 @@ static void assemble_file(const char *fname, StrList **depend_ptr)
|
||||
|
||||
end_of_line:
|
||||
nasm_free(line);
|
||||
location.offset = offs = get_curr_offs();
|
||||
} /* end while (line = preproc->getline... */
|
||||
|
||||
if (pass0 == 2 && global_offset_changed && !terminate_after_phase)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -40,9 +40,14 @@
|
||||
#include "nasmlib.h"
|
||||
#include "insns.h"
|
||||
|
||||
static int32_t next_seg = 0;
|
||||
void seg_alloc_reset(void)
|
||||
{
|
||||
next_seg = 0;
|
||||
}
|
||||
|
||||
int32_t seg_alloc(void)
|
||||
{
|
||||
static int32_t next_seg = 0;
|
||||
int32_t this_seg = next_seg;
|
||||
|
||||
next_seg += 2;
|
||||
|
@ -818,6 +818,11 @@ struct ofmt {
|
||||
*/
|
||||
void (*init)(void);
|
||||
|
||||
/*
|
||||
* This procedure is called at the start of each pass.
|
||||
*/
|
||||
void (*reset)(void);
|
||||
|
||||
/*
|
||||
* This is the modern output function, which gets passed
|
||||
* a struct out_data with much more information. See the
|
||||
@ -891,6 +896,16 @@ struct ofmt {
|
||||
*/
|
||||
int32_t (*section)(char *name, int pass, int *bits);
|
||||
|
||||
/*
|
||||
* This function is called when a label is defined
|
||||
* in the source code. It is allowed to change the section
|
||||
* number as a result, but not the bits value.
|
||||
* This is *only* called if the symbol defined is at the
|
||||
* current offset, i.e. "foo:" or "foo equ $".
|
||||
* The offset isn't passed; and may not be stable at this point.
|
||||
*/
|
||||
int32_t (*herelabel)(const char *name, int32_t seg);
|
||||
|
||||
/*
|
||||
* This procedure is called to modify section alignment,
|
||||
* note there is a trick, the alignment can only increase
|
||||
@ -1231,4 +1246,9 @@ extern int globalbnd; /* default to using bnd prefix? */
|
||||
extern const char *inname; /* primary input filename */
|
||||
extern const char *outname; /* output filename */
|
||||
|
||||
/*
|
||||
* Switch to a different segment and return the current offset
|
||||
*/
|
||||
int64_t switch_segment(int32_t segment);
|
||||
|
||||
#endif
|
||||
|
@ -193,6 +193,7 @@ int64_t readstrnum(char *str, int length, bool *warn);
|
||||
/*
|
||||
* seg_alloc: allocate a hitherto unused segment number.
|
||||
*/
|
||||
void seg_alloc_reset(void);
|
||||
int32_t seg_alloc(void);
|
||||
|
||||
/*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -49,3 +49,8 @@ void null_sectalign(int32_t seg, unsigned int value)
|
||||
(void)seg;
|
||||
(void)value;
|
||||
}
|
||||
|
||||
void null_reset(void)
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
@ -910,10 +910,12 @@ const struct ofmt of_aout = {
|
||||
&null_debug_form,
|
||||
aout_stdmac,
|
||||
aout_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
aout_out,
|
||||
aout_deflabel,
|
||||
aout_section_names,
|
||||
NULL,
|
||||
null_sectalign,
|
||||
aout_segbase,
|
||||
null_directive,
|
||||
@ -935,10 +937,12 @@ const struct ofmt of_aoutb = {
|
||||
&null_debug_form,
|
||||
aout_stdmac,
|
||||
aoutb_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
aout_out,
|
||||
aout_deflabel,
|
||||
aout_section_names,
|
||||
NULL,
|
||||
null_sectalign,
|
||||
aout_segbase,
|
||||
null_directive,
|
||||
|
@ -622,10 +622,12 @@ const struct ofmt of_as86 = {
|
||||
&null_debug_form,
|
||||
as86_stdmac,
|
||||
as86_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
as86_out,
|
||||
as86_deflabel,
|
||||
as86_section_names,
|
||||
NULL,
|
||||
null_sectalign,
|
||||
as86_segbase,
|
||||
null_directive,
|
||||
|
@ -1638,10 +1638,12 @@ const struct ofmt of_bin = {
|
||||
&null_debug_form,
|
||||
bin_stdmac,
|
||||
bin_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
bin_out,
|
||||
bin_deflabel,
|
||||
bin_secname,
|
||||
NULL,
|
||||
bin_sectalign,
|
||||
bin_segbase,
|
||||
bin_directive,
|
||||
@ -1659,10 +1661,12 @@ const struct ofmt of_ith = {
|
||||
&null_debug_form,
|
||||
bin_stdmac,
|
||||
ith_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
bin_out,
|
||||
bin_deflabel,
|
||||
bin_secname,
|
||||
NULL,
|
||||
bin_sectalign,
|
||||
bin_segbase,
|
||||
bin_directive,
|
||||
@ -1680,10 +1684,12 @@ const struct ofmt of_srec = {
|
||||
&null_debug_form,
|
||||
bin_stdmac,
|
||||
srec_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
bin_out,
|
||||
bin_deflabel,
|
||||
bin_secname,
|
||||
NULL,
|
||||
bin_sectalign,
|
||||
bin_segbase,
|
||||
bin_directive,
|
||||
|
@ -1156,10 +1156,12 @@ const struct ofmt of_coff = {
|
||||
&null_debug_form,
|
||||
coff_stdmac,
|
||||
coff_std_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
coff_out,
|
||||
coff_deflabel,
|
||||
coff_section_names,
|
||||
NULL,
|
||||
coff_sectalign,
|
||||
coff_segbase,
|
||||
coff_directives,
|
||||
@ -1185,10 +1187,12 @@ const struct ofmt of_win32 = {
|
||||
&df_cv8,
|
||||
coff_stdmac,
|
||||
coff_win32_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
coff_out,
|
||||
coff_deflabel,
|
||||
coff_section_names,
|
||||
NULL,
|
||||
coff_sectalign,
|
||||
coff_segbase,
|
||||
coff_directives,
|
||||
@ -1212,10 +1216,12 @@ const struct ofmt of_win64 = {
|
||||
&df_cv8,
|
||||
coff_stdmac,
|
||||
coff_win64_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
coff_out,
|
||||
coff_deflabel,
|
||||
coff_section_names,
|
||||
NULL,
|
||||
coff_sectalign,
|
||||
coff_segbase,
|
||||
coff_directives,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -60,6 +60,8 @@ struct Section {
|
||||
|
||||
static unsigned long dbg_max_data_dump = 128;
|
||||
static bool section_labels = true;
|
||||
static bool subsections_via_symbols = false;
|
||||
static int32_t init_seg;
|
||||
|
||||
const struct ofmt of_dbg;
|
||||
static void dbg_init(void)
|
||||
@ -68,6 +70,12 @@ static void dbg_init(void)
|
||||
fprintf(ofile, "NASM Output format debug dump\n");
|
||||
fprintf(ofile, "input file = %s\n", inname);
|
||||
fprintf(ofile, "output file = %s\n", outname);
|
||||
init_seg = seg_alloc();
|
||||
}
|
||||
|
||||
static void dbg_reset(void)
|
||||
{
|
||||
fprintf(ofile, "*** pass reset: pass0 = %d, passn = %d\n", pass0, passn);
|
||||
}
|
||||
|
||||
static void dbg_cleanup(void)
|
||||
@ -93,8 +101,8 @@ static int32_t dbg_add_section(char *name, int pass, int *bits,
|
||||
*bits = 16;
|
||||
|
||||
if (!name) {
|
||||
fprintf(ofile, "section_name on init: returning %d\n",
|
||||
seg = seg_alloc());
|
||||
fprintf(ofile, "section_name on init: returning %d\n", init_seg);
|
||||
seg = init_seg;
|
||||
} else {
|
||||
int n = strcspn(name, " \t");
|
||||
char *sname = nasm_strndup(name, n);
|
||||
@ -127,6 +135,19 @@ static int32_t dbg_section_names(char *name, int pass, int *bits)
|
||||
return dbg_add_section(name, pass, bits, "section_names");
|
||||
}
|
||||
|
||||
static int32_t dbg_herelabel(const char *name, int32_t seg)
|
||||
{
|
||||
int32_t newseg = seg;
|
||||
|
||||
if (subsections_via_symbols && name[0] != 'L')
|
||||
newseg += 0x10000;
|
||||
|
||||
fprintf(ofile, "herelabel %s (seg %08x) -> %08x\n",
|
||||
name, seg, newseg);
|
||||
|
||||
return newseg;
|
||||
}
|
||||
|
||||
static void dbg_deflabel(char *name, int32_t segment, int64_t offset,
|
||||
int is_global, char *special)
|
||||
{
|
||||
@ -363,7 +384,9 @@ dbg_pragma(const struct pragma *pragma)
|
||||
case D_NOSECLABELS:
|
||||
section_labels = false;
|
||||
break;
|
||||
|
||||
case D_SUBSECTIONS_VIA_SYMBOLS:
|
||||
subsections_via_symbols = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -447,10 +470,12 @@ const struct ofmt of_dbg = {
|
||||
&debug_debug_form,
|
||||
dbg_stdmac,
|
||||
dbg_init,
|
||||
dbg_reset,
|
||||
dbg_out,
|
||||
dbg_legacy_out,
|
||||
dbg_deflabel,
|
||||
dbg_section_names,
|
||||
dbg_herelabel,
|
||||
dbg_sectalign,
|
||||
dbg_segbase,
|
||||
dbg_directive,
|
||||
|
@ -2274,10 +2274,12 @@ const struct ofmt of_elf32 = {
|
||||
&elf32_df_stabs,
|
||||
elf_stdmac,
|
||||
elf_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
elf32_out,
|
||||
elf_deflabel,
|
||||
elf_section_names,
|
||||
NULL,
|
||||
elf_sectalign,
|
||||
elf_segbase,
|
||||
elf_directive,
|
||||
@ -2324,10 +2326,12 @@ const struct ofmt of_elf64 = {
|
||||
&elf64_df_stabs,
|
||||
elf_stdmac,
|
||||
elf_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
elf64_out,
|
||||
elf_deflabel,
|
||||
elf_section_names,
|
||||
NULL,
|
||||
elf_sectalign,
|
||||
elf_segbase,
|
||||
elf_directive,
|
||||
@ -2374,10 +2378,12 @@ const struct ofmt of_elfx32 = {
|
||||
&elfx32_df_stabs,
|
||||
elf_stdmac,
|
||||
elf_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
elfx32_out,
|
||||
elf_deflabel,
|
||||
elf_section_names,
|
||||
NULL,
|
||||
elf_sectalign,
|
||||
elf_segbase,
|
||||
elf_directive,
|
||||
|
@ -1506,10 +1506,12 @@ const struct ofmt of_ieee = {
|
||||
&ladsoft_debug_form,
|
||||
NULL,
|
||||
ieee_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
ieee_out,
|
||||
ieee_deflabel,
|
||||
ieee_segment,
|
||||
NULL,
|
||||
ieee_sectalign,
|
||||
ieee_segbase,
|
||||
ieee_directive,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -43,6 +43,7 @@ uint64_t realsize(enum out_type type, uint64_t size);
|
||||
enum directive_result
|
||||
null_directive(enum directive directive, char *value, int pass);
|
||||
void null_sectalign(int32_t seg, unsigned int value);
|
||||
void null_reset(void);
|
||||
|
||||
/* Do-nothing versions of all the debug routines */
|
||||
void null_debug_init(void);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* ----------------------------------------------------------------------- *
|
||||
*
|
||||
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
|
||||
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
|
||||
* See the file AUTHORS included with the NASM distribution for
|
||||
* the specific copyright holders.
|
||||
*
|
||||
@ -153,16 +153,17 @@ struct section {
|
||||
/* nasm internal data */
|
||||
struct section *next;
|
||||
struct SAA *data;
|
||||
int32_t index;
|
||||
uint16_t index; /* Main section index */
|
||||
uint16_t subsection; /* Current subsection */
|
||||
int32_t fileindex;
|
||||
struct reloc *relocs;
|
||||
struct rbtree *syms[2]; /* All/global symbols symbols in section */
|
||||
int align;
|
||||
bool by_name; /* This section was specified by full MachO name */
|
||||
bool by_name; /* This section was specified by full MachO name */
|
||||
|
||||
/* data that goes into the file */
|
||||
char sectname[16]; /* what this section is called */
|
||||
char segname[16]; /* segment this section will be in */
|
||||
char sectname[16]; /* what this section is called */
|
||||
char segname[16]; /* segment this section will be in */
|
||||
uint64_t addr; /* in-memory address (subject to alignment) */
|
||||
uint64_t size; /* in-memory and -file size */
|
||||
uint64_t offset; /* in-file offset */
|
||||
@ -321,10 +322,12 @@ static struct section *get_section_by_name(const char *segname,
|
||||
return s;
|
||||
}
|
||||
|
||||
static struct section *get_section_by_index(const int32_t index)
|
||||
static struct section *get_section_by_index(int32_t index)
|
||||
{
|
||||
struct section *s;
|
||||
|
||||
index &= 0x4000fffe; /* Strip subsection but not absolute flag */
|
||||
|
||||
for (s = sects; s != NULL; s = s->next)
|
||||
if (index == s->index)
|
||||
break;
|
||||
@ -412,6 +415,14 @@ static void macho_init(void)
|
||||
|
||||
}
|
||||
|
||||
static void macho_reset(void)
|
||||
{
|
||||
/* Reset all subsection numbers */
|
||||
struct section *s;
|
||||
for (s = sects; s != NULL; s = s->next)
|
||||
s->subsection = 0;
|
||||
}
|
||||
|
||||
static void sect_write(struct section *sect,
|
||||
const uint8_t *data, uint32_t len)
|
||||
{
|
||||
@ -905,6 +916,7 @@ static int32_t macho_section(char *name, int pass, int *bits)
|
||||
|
||||
s->data = saa_init(1L);
|
||||
s->index = seg_alloc();
|
||||
s->subsection = 0;
|
||||
s->fileindex = ++seg_nsects;
|
||||
s->align = -1;
|
||||
s->pad = -1;
|
||||
@ -987,7 +999,26 @@ static int32_t macho_section(char *name, int pass, int *bits)
|
||||
s->flags |= flags & ~S_NASM_TYPE_MASK;
|
||||
}
|
||||
|
||||
return s->index;
|
||||
return s->index | (s->subsection << 16);
|
||||
}
|
||||
|
||||
static int32_t macho_herelabel(const char *name, int32_t section)
|
||||
{
|
||||
struct section *s;
|
||||
|
||||
if (!(head_flags & MH_SUBSECTIONS_VIA_SYMBOLS))
|
||||
return section;
|
||||
|
||||
/* If it starts with L, it doesn't start a new subsection */
|
||||
if (name[0] == 'L')
|
||||
return section;
|
||||
|
||||
s = get_section_by_index(section);
|
||||
if (!s)
|
||||
return section;
|
||||
|
||||
s->subsection++;
|
||||
return s->index | (s->subsection << 16);
|
||||
}
|
||||
|
||||
static void macho_symdef(char *name, int32_t section, int64_t offset,
|
||||
@ -1740,6 +1771,7 @@ static void macho_cleanup(void)
|
||||
}
|
||||
|
||||
saa_free(strs);
|
||||
|
||||
raa_free(extsyms);
|
||||
|
||||
while (syms) {
|
||||
@ -2328,10 +2360,12 @@ const struct ofmt of_macho32 = {
|
||||
&macho32_df_dwarf,
|
||||
macho_stdmac,
|
||||
macho32_init,
|
||||
macho_reset,
|
||||
nasm_do_legacy_output,
|
||||
macho_output,
|
||||
macho_symdef,
|
||||
macho_section,
|
||||
macho_herelabel,
|
||||
macho_sectalign,
|
||||
macho_segbase,
|
||||
null_directive,
|
||||
@ -2393,10 +2427,12 @@ const struct ofmt of_macho64 = {
|
||||
&macho64_df_dwarf,
|
||||
macho_stdmac,
|
||||
macho64_init,
|
||||
macho_reset,
|
||||
nasm_do_legacy_output,
|
||||
macho_output,
|
||||
macho_symdef,
|
||||
macho_section,
|
||||
macho_herelabel,
|
||||
macho_sectalign,
|
||||
macho_segbase,
|
||||
null_directive,
|
||||
|
@ -2707,10 +2707,12 @@ const struct ofmt of_obj = {
|
||||
&borland_debug_form,
|
||||
obj_stdmac,
|
||||
obj_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
obj_out,
|
||||
obj_deflabel,
|
||||
obj_segment,
|
||||
NULL,
|
||||
obj_sectalign,
|
||||
obj_segbase,
|
||||
obj_directive,
|
||||
|
@ -772,10 +772,12 @@ const struct ofmt of_rdf2 = {
|
||||
&null_debug_form,
|
||||
rdf2_stdmac,
|
||||
rdf2_init,
|
||||
null_reset,
|
||||
nasm_do_legacy_output,
|
||||
rdf2_out,
|
||||
rdf2_deflabel,
|
||||
rdf2_section_names,
|
||||
NULL,
|
||||
null_sectalign,
|
||||
rdf2_segbase,
|
||||
rdf2_directive,
|
||||
|
Loading…
Reference in New Issue
Block a user