0
0
mirror of https://github.com/netwide-assembler/nasm.git synced 2025-09-22 10:43:39 -04:00

subsections: don't lose the offset in the parent section

We don't want to lose the offset into the parent section when we
create a subsection, at least not for the MachO backend which is
currently the only user of subsections. Allow ofmt->herelabel() to set
a flag to copy the section offset from the previous section.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin (Intel)
2018-06-27 20:20:21 -07:00
parent 12810fac92
commit d644119ded
4 changed files with 26 additions and 8 deletions

View File

@@ -351,17 +351,25 @@ handle_herelabel(union label *lptr, int32_t *segment, int64_t *offset)
if (oldseg == location.segment && *offset == location.offset) { if (oldseg == location.segment && *offset == location.offset) {
/* This label is defined at this location */ /* This label is defined at this location */
int32_t newseg; int32_t newseg;
bool copyoffset = false;
nasm_assert(lptr->defn.mangled); nasm_assert(lptr->defn.mangled);
newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type, newseg = ofmt->herelabel(lptr->defn.mangled, lptr->defn.type,
oldseg, &lptr->defn.subsection); oldseg, &lptr->defn.subsection, &copyoffset);
if (likely(newseg == oldseg)) if (likely(newseg == oldseg))
return; return;
*segment = newseg; *segment = newseg;
if (copyoffset) {
/* Maintain the offset from the old to the new segment */
switch_segment(newseg);
location.offset = *offset;
} else {
/* Keep a separate offset for the new segment */
*offset = switch_segment(newseg); *offset = switch_segment(newseg);
} }
} }
}
static bool declare_label_lptr(union label *lptr, static bool declare_label_lptr(union label *lptr,
enum label_type type, const char *special) enum label_type type, const char *special)

View File

@@ -911,9 +911,14 @@ struct ofmt {
* The offset isn't passed; and may not be stable at this point. * The offset isn't passed; and may not be stable at this point.
* The subsection number is a field available for use by the * The subsection number is a field available for use by the
* backend. It is initialized to NO_SEG. * backend. It is initialized to NO_SEG.
*
* If "copyoffset" is set by the backend then the offset is
* copied from the previous segment, otherwise the new segment
* is treated as a new segment the normal way.
*/ */
int32_t (*herelabel)(const char *name, enum label_type type, int32_t (*herelabel)(const char *name, enum label_type type,
int32_t seg, int32_t *subsection); int32_t seg, int32_t *subsection,
bool *copyoffset);
/* /*
* This procedure is called to modify section alignment, * This procedure is called to modify section alignment,

View File

@@ -137,14 +137,17 @@ static int32_t dbg_section_names(char *name, int pass, int *bits)
} }
static int32_t dbg_herelabel(const char *name, enum label_type type, static int32_t dbg_herelabel(const char *name, enum label_type type,
int32_t oldseg, int32_t *subsection) int32_t oldseg, int32_t *subsection,
bool *copyoffset)
{ {
int32_t newseg = oldseg; int32_t newseg = oldseg;
if (subsections_via_symbols && type != LBL_LOCAL) { if (subsections_via_symbols && type != LBL_LOCAL) {
newseg = *subsection; newseg = *subsection;
if (newseg == NO_SEG) if (newseg == NO_SEG) {
newseg = *subsection = seg_alloc(); newseg = *subsection = seg_alloc();
*copyoffset = true; /* Minic MachO for now */
}
} }
fprintf(ofile, "herelabel %s type %d (seg %08x) -> %08x\n", fprintf(ofile, "herelabel %s type %d (seg %08x) -> %08x\n",
name, type, oldseg, newseg); name, type, oldseg, newseg);

View File

@@ -1018,7 +1018,8 @@ static int32_t macho_section(char *name, int pass, int *bits)
} }
static int32_t macho_herelabel(const char *name, enum label_type type, static int32_t macho_herelabel(const char *name, enum label_type type,
int32_t section, int32_t *subsection) int32_t section, int32_t *subsection,
bool *copyoffset)
{ {
struct section *s; struct section *s;
int32_t subsec; int32_t subsec;
@@ -1043,6 +1044,7 @@ static int32_t macho_herelabel(const char *name, enum label_type type,
} }
s->subsection = subsec; s->subsection = subsec;
*copyoffset = true; /* Maintain previous offset */
return subsec; return subsec;
} }
@@ -1055,8 +1057,8 @@ static void macho_symdef(char *name, int32_t section, int64_t offset,
#if defined(DEBUG) && DEBUG>2 #if defined(DEBUG) && DEBUG>2
nasm_error(ERR_DEBUG, nasm_error(ERR_DEBUG,
" macho_symdef: %s, sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n", " macho_symdef: %s, pass0=%d, passn=%"PRId64", sec=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
name, section, offset, is_global, special); name, pass0, passn, section, offset, is_global, special);
#endif #endif
if (is_global == 3) { if (is_global == 3) {