mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-29 15:00:34 +00:00
Changes to let cons handle bignums like general expressions.
* expr.h (expressionS): New field X_unsigned. * expr.c (operand): Initialize X_unsigned to 1. Set it to 0 for unary minus case. (expr) Fix typo resultP to right if missing operand. Set X_unsigned to 1 when building new expression. * read.c (potable): Make "octa" and "quad" call cons, not big_cons. (cons): Handle bignums. If given an O_constant (small integer) to fill a big space, turn it into a bignum. (parse_bitfield_cons): Set X_unsigned field. (bignum_low, bignum_limit, bignum_high, grow_bignum, big_cons): Removed. * read.h (big_cons): Remove prototype. * symbols.c (resolve_symbol_value): Don't give a warning if a symbol in expr_section can not be resolved. (S_SET_VALUE): Clear X_unsigned. * write.c (write_object_file): If resolve_symbol_value failed on a symbol we are writing out, give a warning. * config/tc-h8500.c (parse_reglist): Set X_unsigned. * config/tc-hppa.c (md_pseudo_table): Change "octa" and "quad" to call pa_cons, not pa_big_cons. (pa_big_cons): Remove. * config/tc-hppa.h (pa_big_cons): Remove declaration. * config/tc-i960.c (md_pseudo_table): Change "quad" to call cons, not big_cons.
This commit is contained in:
parent
9978cd4dc9
commit
80aab57939
@ -1,3 +1,37 @@
|
||||
Wed Oct 6 13:01:34 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
Changes to let cons handle bignums like general expressions.
|
||||
* expr.h (expressionS): New field X_unsigned.
|
||||
* expr.c (operand): Initialize X_unsigned to 1. Set it to 0 for
|
||||
unary minus case.
|
||||
(expr) Fix typo resultP to right if missing operand. Set
|
||||
X_unsigned to 1 when building new expression.
|
||||
* read.c (potable): Make "octa" and "quad" call cons, not
|
||||
big_cons.
|
||||
(cons): Handle bignums. If given an O_constant (small integer) to
|
||||
fill a big space, turn it into a bignum.
|
||||
(parse_bitfield_cons): Set X_unsigned field.
|
||||
(bignum_low, bignum_limit, bignum_high, grow_bignum, big_cons):
|
||||
Removed.
|
||||
* read.h (big_cons): Remove prototype.
|
||||
* symbols.c (resolve_symbol_value): Don't give a warning if a
|
||||
symbol in expr_section can not be resolved.
|
||||
(S_SET_VALUE): Clear X_unsigned.
|
||||
* write.c (write_object_file): If resolve_symbol_value failed on a
|
||||
symbol we are writing out, give a warning.
|
||||
* config/tc-h8500.c (parse_reglist): Set X_unsigned.
|
||||
* config/tc-hppa.c (md_pseudo_table): Change "octa" and "quad" to
|
||||
call pa_cons, not pa_big_cons.
|
||||
(pa_big_cons): Remove.
|
||||
* config/tc-hppa.h (pa_big_cons): Remove declaration.
|
||||
* config/tc-i960.c (md_pseudo_table): Change "quad" to call cons,
|
||||
not big_cons.
|
||||
|
||||
Tue Oct 5 10:53:36 1993 david d `zoo' zuhn (zoo@rtl.cygnus.com)
|
||||
|
||||
* doc/as.texinfo (Copying): new node, to handle the recent changes
|
||||
in the texinfo/gpl.texinfo file
|
||||
|
||||
Mon Oct 4 17:10:15 1993 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
|
||||
|
||||
* read.c (big_cons): Handle "0" correctly.
|
||||
|
@ -421,6 +421,7 @@ parse_reglist (src, op)
|
||||
op->exp.X_op_symbol = 0;
|
||||
op->exp.X_add_number = mask;
|
||||
op->exp.X_op = O_constant;
|
||||
op->exp.X_unsigned = 1;
|
||||
op->type = IMM8;
|
||||
return idx;
|
||||
|
||||
|
@ -233,8 +233,8 @@ const pseudo_typeS
|
||||
{"LONG", pa_cons, 4},
|
||||
{"lsym", pa_lsym, 0},
|
||||
{"LSYM", pa_lsym, 0},
|
||||
{"octa", pa_big_cons, 16},
|
||||
{"OCTA", pa_big_cons, 16},
|
||||
{"octa", pa_cons, 16},
|
||||
{"OCTA", pa_cons, 16},
|
||||
{"org", pa_origin, 0},
|
||||
{"ORG", pa_origin, 0},
|
||||
{"origin", pa_origin, 0},
|
||||
@ -245,8 +245,8 @@ const pseudo_typeS
|
||||
{"PROC", pa_proc, 0},
|
||||
{"procend", pa_procend, 0},
|
||||
{"PROCEND", pa_procend, 0},
|
||||
{"quad", pa_big_cons, 8},
|
||||
{"QUAD", pa_big_cons, 8},
|
||||
{"quad", pa_cons, 8},
|
||||
{"QUAD", pa_cons, 8},
|
||||
{"reg", pa_equ, 1}, /* very similar to .equ */
|
||||
{"REG", pa_equ, 1}, /* very similar to .equ */
|
||||
{"short", pa_cons, 2},
|
||||
@ -732,7 +732,7 @@ md_begin ()
|
||||
{
|
||||
const char *name = pa_opcodes[i].name;
|
||||
retval = hash_insert (op_hash, name, &pa_opcodes[i]);
|
||||
if (retval != NULL && *retval != '\0')
|
||||
if (retval != NULL)
|
||||
{
|
||||
as_fatal ("Internal error: can't hash `%s': %s\n",
|
||||
pa_opcodes[i].name, retval);
|
||||
@ -4291,13 +4291,13 @@ s_seg ()
|
||||
if (strncmp (input_line_pointer, "\"text\"", 6) == 0)
|
||||
{
|
||||
input_line_pointer += 6;
|
||||
s_text ();
|
||||
s_text (0);
|
||||
return;
|
||||
}
|
||||
if (strncmp (input_line_pointer, "\"data\"", 6) == 0)
|
||||
{
|
||||
input_line_pointer += 6;
|
||||
s_data ();
|
||||
s_data (0);
|
||||
return;
|
||||
}
|
||||
if (strncmp (input_line_pointer, "\"data1\"", 7) == 0)
|
||||
@ -4317,22 +4317,14 @@ s_private ()
|
||||
register int temp;
|
||||
|
||||
temp = get_absolute_expression ();
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (SEG_DATA, (subsegT) temp);
|
||||
#else
|
||||
subseg_new (".data", (subsegT) temp);
|
||||
#endif
|
||||
subseg_set (data_section, (subsegT) temp);
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
||||
void
|
||||
s_data1 ()
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (SEG_DATA, 1);
|
||||
#else
|
||||
subseg_new (".data", 1);
|
||||
#endif
|
||||
subseg_set (data_section, 1);
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -4498,7 +4490,7 @@ pa_build_unwind_subspace (call_info)
|
||||
|
||||
save_seg = now_seg;
|
||||
save_subseg = now_subseg;
|
||||
subseg_new ((char *) seg->name, subseg);
|
||||
subseg_set (seg, subseg);
|
||||
unwindP = (char *) &call_info->ci_unwind;
|
||||
|
||||
p = frag_more (4);
|
||||
@ -4567,7 +4559,7 @@ pa_build_unwind_subspace (call_info)
|
||||
}
|
||||
}
|
||||
|
||||
subseg_new ((char *) save_seg->name, save_subseg);
|
||||
subseg_set (save_seg, save_subseg);
|
||||
}
|
||||
|
||||
#else
|
||||
@ -4625,7 +4617,7 @@ pa_build_unwind_subspace (call_info)
|
||||
|
||||
save_seg = now_seg;
|
||||
save_subseg = now_subseg;
|
||||
subseg_new (seg, subseg);
|
||||
subseg_set (seg, subseg);
|
||||
unwindP = (char *) &call_info->ci_unwind;
|
||||
|
||||
p = frag_more (4);
|
||||
@ -4710,7 +4702,7 @@ pa_build_unwind_subspace (call_info)
|
||||
}
|
||||
}
|
||||
|
||||
subseg_new (save_seg, save_subseg);
|
||||
subseg_set (save_seg, save_subseg);
|
||||
|
||||
}
|
||||
|
||||
@ -4834,13 +4826,8 @@ pa_code ()
|
||||
}
|
||||
|
||||
SPACE_DEFINED (sdchain) = 1;
|
||||
#ifdef OBJ_SOM
|
||||
|
||||
subseg_new (SEG_TEXT, SUBSEG_CODE);
|
||||
#else
|
||||
|
||||
subseg_new (".text", SUBSEG_CODE);
|
||||
#endif
|
||||
subseg_set (text_section, SUBSEG_CODE);
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
@ -5210,7 +5197,7 @@ void
|
||||
seg,
|
||||
SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC | SEC_LOAD);
|
||||
|
||||
subseg_new(save_seg->name, save_subseg);
|
||||
subseg_set(save_seg, save_subseg);
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -5520,7 +5507,7 @@ pa_leave ()
|
||||
void
|
||||
pa_origin ()
|
||||
{
|
||||
s_org (); /* ORG actually allows another argument
|
||||
s_org (0); /* ORG actually allows another argument
|
||||
(the fill value) but maybe this is OK? */
|
||||
pa_undefine_label ();
|
||||
return;
|
||||
@ -5787,11 +5774,7 @@ pa_parse_space_stmt (space_name, create_flag)
|
||||
|
||||
void
|
||||
pa_align_subseg (seg, subseg)
|
||||
#ifdef OBJ_SOM
|
||||
segT seg;
|
||||
#else
|
||||
asection *seg;
|
||||
#endif
|
||||
subsegT subseg;
|
||||
{
|
||||
subspace_dict_chainS *now_subspace;
|
||||
@ -5841,22 +5824,12 @@ pa_space ()
|
||||
current_space = sd_chain;
|
||||
SPACE_DEFINED (current_space) = 1;
|
||||
current_space->sd_defined = 1;
|
||||
#ifdef OBJ_SOM
|
||||
if (now_seg != SEG_TEXT) /* no need to align if we are already there */
|
||||
#else
|
||||
if (now_seg != text_section) /* no need to align if we are already there */
|
||||
#endif
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (SEG_TEXT, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (SEG_TEXT,
|
||||
sd_chain->sd_last_subseg);
|
||||
#else
|
||||
subseg_new ((char *) text_section->name, sd_chain->sd_last_subseg);
|
||||
subseg_set (text_section, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (text_section,
|
||||
sd_chain->sd_last_subseg);
|
||||
#endif
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -5872,21 +5845,11 @@ pa_space ()
|
||||
current_space = sd_chain;
|
||||
SPACE_DEFINED (current_space) = 1;
|
||||
current_space->sd_defined = 1;
|
||||
#ifdef OBJ_SOM
|
||||
if (now_seg != SEG_DATA) /* no need to align if we are already there */
|
||||
#else
|
||||
if (now_seg != data_section) /* no need to align if we are already there */
|
||||
#endif
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (SEG_DATA, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (SEG_DATA,
|
||||
sd_chain->sd_last_subseg);
|
||||
#else
|
||||
subseg_new ((char *) data_section->name, sd_chain->sd_last_subseg);
|
||||
subseg_set (data_section, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (data_section,
|
||||
sd_chain->sd_last_subseg);
|
||||
#endif
|
||||
demand_empty_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
@ -5903,19 +5866,22 @@ pa_space ()
|
||||
current_space = sd_chain;
|
||||
SPACE_DEFINED (current_space) = 1;
|
||||
current_space->sd_defined = 1;
|
||||
|
||||
#ifdef OBJ_SOM
|
||||
if (now_seg != SEG_GDB) /* no need to align if we are already there */
|
||||
if (now_seg != SEG_GDB) /* no need to align if we are already there */
|
||||
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
subseg_new (SEG_GDB, sd_chain->sd_last_subseg);
|
||||
subseg_set (SEG_GDB, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (SEG_GDB,
|
||||
sd_chain->sd_last_subseg);
|
||||
#else
|
||||
{
|
||||
asection *gdb_section
|
||||
= bfd_make_section_old_way (stdoutput, GDB_DEBUG_SPACE_NAME);
|
||||
if (now_seg != gdb_section) /* no need to align if we are already there */
|
||||
segT gdb_section;
|
||||
/* no need to align if we are already there */
|
||||
if (strcmp (segment_name (now_seg), GDB_DEBUG_SPACE_NAME) != 0)
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
subseg_new ((char *) gdb_section->name, sd_chain->sd_last_subseg);
|
||||
gdb_section = subseg_new (GDB_DEBUG_SPACE_NAME,
|
||||
sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (gdb_section,
|
||||
sd_chain->sd_last_subseg);
|
||||
}
|
||||
@ -5935,11 +5901,7 @@ pa_space ()
|
||||
current_space->sd_defined = 1;
|
||||
if (now_seg != sd_chain->sd_seg) /* don't align if we're already there */
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (sd_chain->sd_seg, sd_chain->sd_last_subseg);
|
||||
#else
|
||||
subseg_new ((char *) sd_chain->sd_seg->name, sd_chain->sd_last_subseg);
|
||||
#endif
|
||||
subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
|
||||
sd_chain->sd_last_subseg);
|
||||
demand_empty_rest_of_line ();
|
||||
@ -5961,11 +5923,7 @@ pa_space ()
|
||||
current_space->sd_defined = 1;
|
||||
if (now_seg != sd_chain->sd_seg) /* don't align if we're already there */
|
||||
pa_align_subseg (now_seg, now_subseg);
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (sd_chain->sd_seg, sd_chain->sd_last_subseg);
|
||||
#else
|
||||
subseg_new ((char *) sd_chain->sd_seg->name, sd_chain->sd_last_subseg);
|
||||
#endif
|
||||
subseg_set (sd_chain->sd_seg, sd_chain->sd_last_subseg);
|
||||
current_subspace = pa_subsegment_to_subspace (sd_chain->sd_seg,
|
||||
sd_chain->sd_last_subseg);
|
||||
demand_empty_rest_of_line ();
|
||||
@ -6068,7 +6026,7 @@ pa_subspace ()
|
||||
if (ssd->ssd_defined)
|
||||
{
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (now_seg, ssd->ssd_subseg);
|
||||
subseg_set (now_seg, ssd->ssd_subseg);
|
||||
#else
|
||||
/* subseg_new(now_seg->name,ssd->ssd_subseg); */
|
||||
subseg_new ((char *) ssd->ssd_seg->name, ssd->ssd_subseg);
|
||||
@ -6202,11 +6160,7 @@ pa_subspace ()
|
||||
SUBSPACE_SUBSPACE_START (current_subspace) = pa_subspace_start (space, quadrant);
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
#ifdef OBJ_SOM
|
||||
subseg_new (current_subspace->ssd_seg, current_subspace->ssd_subseg);
|
||||
#else
|
||||
subseg_new ((char *) current_subspace->ssd_seg->name, current_subspace->ssd_subseg);
|
||||
#endif
|
||||
subseg_set (current_subspace->ssd_seg, current_subspace->ssd_subseg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -6887,7 +6841,7 @@ pa_cons (nbytes)
|
||||
void
|
||||
pa_data ()
|
||||
{
|
||||
s_data ();
|
||||
s_data (0);
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
@ -6912,7 +6866,7 @@ pa_float_cons (float_type)
|
||||
void
|
||||
pa_fill ()
|
||||
{
|
||||
s_fill ();
|
||||
s_fill (0);
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
@ -6929,22 +6883,14 @@ pa_lcomm (needs_align)
|
||||
void
|
||||
pa_lsym ()
|
||||
{
|
||||
s_lsym ();
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
void
|
||||
pa_big_cons (nbytes)
|
||||
register int nbytes;
|
||||
{
|
||||
big_cons (nbytes);
|
||||
s_lsym (0);
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
void
|
||||
pa_text ()
|
||||
{
|
||||
s_text ();
|
||||
s_text (0);
|
||||
pa_undefine_label ();
|
||||
}
|
||||
|
||||
@ -7043,7 +6989,7 @@ bfd * abfd;
|
||||
|
||||
/* now, switch back to the original segment */
|
||||
|
||||
subseg_new(save_seg->name, save_subseg);
|
||||
subseg_set(save_seg, save_subseg);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -7073,6 +7019,6 @@ hppa_tc_make_symextn_section()
|
||||
bfd_set_section_size (stdoutput, symextn_sec, size);
|
||||
|
||||
/* now, switch back to the original segment */
|
||||
subseg_new(save_seg->name, save_subseg);
|
||||
subseg_set(save_seg, save_subseg);
|
||||
}
|
||||
}
|
||||
|
@ -201,7 +201,7 @@ const pseudo_typeS md_pseudo_table[] =
|
||||
{"sysproc", parse_po, S_SYSPROC},
|
||||
|
||||
{"word", cons, 4},
|
||||
{"quad", big_cons, 16},
|
||||
{"quad", cons, 16},
|
||||
|
||||
{0, 0, 0}
|
||||
};
|
||||
@ -508,41 +508,31 @@ md_begin ()
|
||||
{
|
||||
int i; /* Loop counter */
|
||||
const struct i960_opcode *oP; /* Pointer into opcode table */
|
||||
char *retval; /* Value returned by hash functions */
|
||||
const char *retval; /* Value returned by hash functions */
|
||||
|
||||
if (((op_hash = hash_new ()) == 0)
|
||||
|| ((reg_hash = hash_new ()) == 0)
|
||||
|| ((areg_hash = hash_new ()) == 0))
|
||||
{
|
||||
as_fatal ("virtual memory exceeded");
|
||||
}
|
||||
as_fatal ("virtual memory exceeded");
|
||||
|
||||
/* For some reason, the base assembler uses an empty string for "no
|
||||
error message", instead of a NULL pointer. */
|
||||
retval = "";
|
||||
|
||||
for (oP = i960_opcodes; oP->name && !*retval; oP++)
|
||||
{
|
||||
retval = hash_insert (op_hash, oP->name, oP);
|
||||
}
|
||||
for (oP = i960_opcodes; oP->name && !retval; oP++)
|
||||
retval = hash_insert (op_hash, oP->name, (PTR) oP);
|
||||
|
||||
for (i = 0; regnames[i].reg_name && !*retval; i++)
|
||||
{
|
||||
retval = hash_insert (reg_hash, regnames[i].reg_name,
|
||||
®names[i].reg_num);
|
||||
}
|
||||
for (i = 0; regnames[i].reg_name && !retval; i++)
|
||||
retval = hash_insert (reg_hash, regnames[i].reg_name,
|
||||
®names[i].reg_num);
|
||||
|
||||
for (i = 0; aregs[i].areg_name && !*retval; i++)
|
||||
{
|
||||
retval = hash_insert (areg_hash, aregs[i].areg_name,
|
||||
&aregs[i].areg_num);
|
||||
}
|
||||
for (i = 0; aregs[i].areg_name && !retval; i++)
|
||||
retval = hash_insert (areg_hash, aregs[i].areg_name,
|
||||
&aregs[i].areg_num);
|
||||
|
||||
if (*retval)
|
||||
{
|
||||
as_fatal ("Hashing returned \"%s\".", retval);
|
||||
}
|
||||
} /* md_begin() */
|
||||
if (retval)
|
||||
as_fatal ("Hashing returned \"%s\".", retval);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* md_end: One-time final cleanup
|
||||
@ -577,7 +567,6 @@ md_assemble (textP)
|
||||
char *args[4];
|
||||
|
||||
int n_ops; /* Number of instruction operands */
|
||||
int callx;
|
||||
/* Pointer to instruction description */
|
||||
struct i960_opcode *oP;
|
||||
/* TRUE iff opcode mnemonic included branch-prediction
|
||||
@ -896,7 +885,7 @@ md_number_to_field (instrP, val, bfixP)
|
||||
if (((val < 0) && (sign != -1))
|
||||
|| ((val > 0) && (sign != 0)))
|
||||
{
|
||||
as_bad ("Fixup of %d too large for field width of %d",
|
||||
as_bad ("Fixup of %ld too large for field width of %d",
|
||||
val, numbits);
|
||||
}
|
||||
else
|
||||
@ -964,14 +953,14 @@ md_parse_option (argP, cntP, vecP)
|
||||
};
|
||||
static struct tabentry arch_tab[] =
|
||||
{
|
||||
"KA", ARCH_KA,
|
||||
"KB", ARCH_KB,
|
||||
"SA", ARCH_KA, /* Synonym for KA */
|
||||
"SB", ARCH_KB, /* Synonym for KB */
|
||||
"KC", ARCH_MC, /* Synonym for MC */
|
||||
"MC", ARCH_MC,
|
||||
"CA", ARCH_CA,
|
||||
NULL, 0
|
||||
{ "KA", ARCH_KA },
|
||||
{ "KB", ARCH_KB },
|
||||
{ "SA", ARCH_KA }, /* Synonym for KA */
|
||||
{ "SB", ARCH_KB }, /* Synonym for KB */
|
||||
{ "KC", ARCH_MC }, /* Synonym for MC */
|
||||
{ "MC", ARCH_MC },
|
||||
{ "CA", ARCH_CA },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
struct tabentry *tp;
|
||||
if (!strcmp (*argP, "linkrelax"))
|
||||
@ -2220,7 +2209,7 @@ parse_po (po_num)
|
||||
|
||||
/* Advance input pointer to end of line. */
|
||||
p = input_line_pointer;
|
||||
while (!is_end_of_line[*input_line_pointer])
|
||||
while (!is_end_of_line[(unsigned char) *input_line_pointer])
|
||||
{
|
||||
input_line_pointer++;
|
||||
}
|
||||
@ -2458,22 +2447,22 @@ struct
|
||||
|
||||
coj[] =
|
||||
{ /* COBR OPCODE: */
|
||||
CHKBIT, BNO, /* 0x30 - bbc */
|
||||
CMPO, BG, /* 0x31 - cmpobg */
|
||||
CMPO, BE, /* 0x32 - cmpobe */
|
||||
CMPO, BGE, /* 0x33 - cmpobge */
|
||||
CMPO, BL, /* 0x34 - cmpobl */
|
||||
CMPO, BNE, /* 0x35 - cmpobne */
|
||||
CMPO, BLE, /* 0x36 - cmpoble */
|
||||
CHKBIT, BO, /* 0x37 - bbs */
|
||||
CMPI, BNO, /* 0x38 - cmpibno */
|
||||
CMPI, BG, /* 0x39 - cmpibg */
|
||||
CMPI, BE, /* 0x3a - cmpibe */
|
||||
CMPI, BGE, /* 0x3b - cmpibge */
|
||||
CMPI, BL, /* 0x3c - cmpibl */
|
||||
CMPI, BNE, /* 0x3d - cmpibne */
|
||||
CMPI, BLE, /* 0x3e - cmpible */
|
||||
CMPI, BO, /* 0x3f - cmpibo */
|
||||
{ CHKBIT, BNO }, /* 0x30 - bbc */
|
||||
{ CMPO, BG }, /* 0x31 - cmpobg */
|
||||
{ CMPO, BE }, /* 0x32 - cmpobe */
|
||||
{ CMPO, BGE }, /* 0x33 - cmpobge */
|
||||
{ CMPO, BL }, /* 0x34 - cmpobl */
|
||||
{ CMPO, BNE }, /* 0x35 - cmpobne */
|
||||
{ CMPO, BLE }, /* 0x36 - cmpoble */
|
||||
{ CHKBIT, BO }, /* 0x37 - bbs */
|
||||
{ CMPI, BNO }, /* 0x38 - cmpibno */
|
||||
{ CMPI, BG }, /* 0x39 - cmpibg */
|
||||
{ CMPI, BE }, /* 0x3a - cmpibe */
|
||||
{ CMPI, BGE }, /* 0x3b - cmpibge */
|
||||
{ CMPI, BL }, /* 0x3c - cmpibl */
|
||||
{ CMPI, BNE }, /* 0x3d - cmpibne */
|
||||
{ CMPI, BLE }, /* 0x3e - cmpible */
|
||||
{ CMPI, BO }, /* 0x3f - cmpibo */
|
||||
};
|
||||
|
||||
static
|
||||
@ -3174,10 +3163,6 @@ i960_handle_align (fragp)
|
||||
fragS *fragp;
|
||||
{
|
||||
fixS *fixp;
|
||||
segT old_seg = now_seg, this_seg;
|
||||
int old_subseg = now_subseg;
|
||||
int pad_size;
|
||||
extern struct frag *text_last_frag, *data_last_frag;
|
||||
|
||||
if (!linkrelax)
|
||||
return;
|
||||
|
758
gas/read.c
758
gas/read.c
@ -133,12 +133,6 @@ char is_end_of_line[256] =
|
||||
static char *buffer; /* 1st char of each buffer of lines is here. */
|
||||
static char *buffer_limit; /*->1 + last char in buffer. */
|
||||
|
||||
static char *bignum_low; /* Lowest char of bignum. */
|
||||
static char *bignum_limit; /* 1st illegal address of bignum. */
|
||||
static char *bignum_high; /* Highest char of bignum. */
|
||||
/* May point to (bignum_start-1). */
|
||||
/* Never >= bignum_limit. */
|
||||
|
||||
int target_big_endian;
|
||||
|
||||
static char *old_buffer; /* JF a hack */
|
||||
@ -161,10 +155,7 @@ static char *demand_copy_string PARAMS ((int *lenP));
|
||||
int is_it_end_of_statement PARAMS ((void));
|
||||
static segT get_segmented_expression PARAMS ((expressionS *expP));
|
||||
static segT get_known_segmented_expression PARAMS ((expressionS * expP));
|
||||
static void grow_bignum PARAMS ((void));
|
||||
static void pobegin PARAMS ((void));
|
||||
|
||||
extern int listing;
|
||||
|
||||
|
||||
void
|
||||
@ -180,10 +171,6 @@ read_begin ()
|
||||
obstack_begin (¬es, 5090);
|
||||
obstack_begin (&cond_obstack, 990);
|
||||
|
||||
#define BIGNUM_BEGIN_SIZE (16)
|
||||
bignum_low = xmalloc ((long) BIGNUM_BEGIN_SIZE);
|
||||
bignum_limit = bignum_low + BIGNUM_BEGIN_SIZE;
|
||||
|
||||
/* Use machine dependent syntax */
|
||||
for (p = line_separator_chars; *p; p++)
|
||||
is_end_of_line[(unsigned char) *p] = 1;
|
||||
@ -241,11 +228,11 @@ static const pseudo_typeS potable[] =
|
||||
{"long", cons, 4},
|
||||
{"lsym", s_lsym, 0},
|
||||
{"nolist", listing_list, 0}, /* Turn listing off */
|
||||
{"octa", big_cons, 16},
|
||||
{"octa", cons, 16},
|
||||
{"org", s_org, 0},
|
||||
{"psize", listing_psize, 0}, /* set paper size */
|
||||
/* print */
|
||||
{"quad", big_cons, 8},
|
||||
{"quad", cons, 8},
|
||||
{"sbttl", listing_title, 1}, /* Subtitle of listing */
|
||||
/* scl */
|
||||
/* sect */
|
||||
@ -281,7 +268,7 @@ pobegin ()
|
||||
for (pop = md_pseudo_table; pop->poc_name; pop++)
|
||||
{
|
||||
errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
|
||||
if (errtxt && *errtxt)
|
||||
if (errtxt)
|
||||
{
|
||||
as_fatal ("error constructing md pseudo-op table");
|
||||
} /* on error */
|
||||
@ -291,7 +278,7 @@ pobegin ()
|
||||
for (pop = obj_pseudo_table; pop->poc_name; pop++)
|
||||
{
|
||||
errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
|
||||
if (errtxt && *errtxt)
|
||||
if (errtxt)
|
||||
{
|
||||
if (!strcmp (errtxt, "exists"))
|
||||
{
|
||||
@ -311,7 +298,7 @@ pobegin ()
|
||||
for (pop = potable; pop->poc_name; pop++)
|
||||
{
|
||||
errtxt = hash_insert (po_hash, pop->poc_name, (char *) pop);
|
||||
if (errtxt && *errtxt)
|
||||
if (errtxt)
|
||||
{
|
||||
if (!strcmp (errtxt, "exists"))
|
||||
{
|
||||
@ -1529,7 +1516,7 @@ pseudo_set (symbolP)
|
||||
*
|
||||
* CONStruct more frag of .bytes, or .words etc.
|
||||
* Should need_pass_2 be 1 then emit no frag(s).
|
||||
* This understands EXPRESSIONS, as opposed to big_cons().
|
||||
* This understands EXPRESSIONS.
|
||||
*
|
||||
* Bug (?)
|
||||
*
|
||||
@ -1608,6 +1595,7 @@ emit_expr (exp, nbytes)
|
||||
{
|
||||
operatorT op;
|
||||
register char *p;
|
||||
valueT extra_digit = 0;
|
||||
|
||||
/* Don't do anything if we are going to make another pass. */
|
||||
if (need_pass_2)
|
||||
@ -1615,16 +1603,46 @@ emit_expr (exp, nbytes)
|
||||
|
||||
op = exp->X_op;
|
||||
|
||||
/* Handle a negative bignum. */
|
||||
if (op == O_uminus
|
||||
&& exp->X_add_number == 0
|
||||
&& exp->X_add_symbol->sy_value.X_op == O_big
|
||||
&& exp->X_add_symbol->sy_value.X_add_number > 0)
|
||||
{
|
||||
int i;
|
||||
unsigned long carry;
|
||||
|
||||
exp = &exp->X_add_symbol->sy_value;
|
||||
|
||||
/* Negate the bignum: one's complement each digit and add 1. */
|
||||
carry = 1;
|
||||
for (i = 0; i < exp->X_add_number; i++)
|
||||
{
|
||||
unsigned long next;
|
||||
|
||||
next = (((~ (generic_bignum[i] & LITTLENUM_MASK))
|
||||
& LITTLENUM_MASK)
|
||||
+ carry);
|
||||
generic_bignum[i] = next & LITTLENUM_MASK;
|
||||
carry = next >> LITTLENUM_NUMBER_OF_BITS;
|
||||
}
|
||||
|
||||
/* We can ignore any carry out, because it will be handled by
|
||||
extra_digit if it is needed. */
|
||||
|
||||
extra_digit = (valueT) -1;
|
||||
op = O_big;
|
||||
}
|
||||
|
||||
if (op == O_absent || op == O_illegal)
|
||||
{
|
||||
as_warn ("zero assumed for missing expression");
|
||||
exp->X_add_number = 0;
|
||||
op = O_constant;
|
||||
}
|
||||
else if (op == O_big)
|
||||
else if (op == O_big && exp->X_add_number <= 0)
|
||||
{
|
||||
as_bad ("%s number invalid; zero assumed",
|
||||
exp->X_add_number > 0 ? "bignum" : "floating point");
|
||||
as_bad ("floating point number invalid; zero assumed");
|
||||
exp->X_add_number = 0;
|
||||
op = O_constant;
|
||||
}
|
||||
@ -1658,6 +1676,28 @@ emit_expr (exp, nbytes)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If we have an integer, but the number of bytes is too large to
|
||||
pass to md_number_to_chars, handle it as a bignum. */
|
||||
if (op == O_constant && nbytes > sizeof (valueT))
|
||||
{
|
||||
valueT val;
|
||||
int gencnt;
|
||||
|
||||
if (! exp->X_unsigned && exp->X_add_number < 0)
|
||||
extra_digit = (valueT) -1;
|
||||
val = (valueT) exp->X_add_number;
|
||||
gencnt = 0;
|
||||
do
|
||||
{
|
||||
generic_bignum[gencnt] = val & LITTLENUM_MASK;
|
||||
val >>= LITTLENUM_NUMBER_OF_BITS;
|
||||
++gencnt;
|
||||
}
|
||||
while (val != 0);
|
||||
op = exp->X_op = O_big;
|
||||
exp->X_add_number = gencnt;
|
||||
}
|
||||
|
||||
if (op == O_constant)
|
||||
{
|
||||
register long get;
|
||||
@ -1688,6 +1728,58 @@ emit_expr (exp, nbytes)
|
||||
/* put bytes in right order. */
|
||||
md_number_to_chars (p, (valueT) use, (int) nbytes);
|
||||
}
|
||||
else if (op == O_big)
|
||||
{
|
||||
int size;
|
||||
LITTLENUM_TYPE *nums;
|
||||
|
||||
know (nbytes % CHARS_PER_LITTLENUM == 0);
|
||||
|
||||
size = exp->X_add_number * CHARS_PER_LITTLENUM;
|
||||
if (nbytes < size)
|
||||
{
|
||||
as_warn ("Bignum truncated to %d bytes", nbytes);
|
||||
size = nbytes;
|
||||
}
|
||||
|
||||
if (target_big_endian)
|
||||
{
|
||||
while (nbytes > size)
|
||||
{
|
||||
md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
|
||||
nbytes -= CHARS_PER_LITTLENUM;
|
||||
p += CHARS_PER_LITTLENUM;
|
||||
}
|
||||
|
||||
nums = generic_bignum + size / CHARS_PER_LITTLENUM;
|
||||
while (size > 0)
|
||||
{
|
||||
--nums;
|
||||
md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
|
||||
size -= CHARS_PER_LITTLENUM;
|
||||
p += CHARS_PER_LITTLENUM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
nums = generic_bignum;
|
||||
while (size > 0)
|
||||
{
|
||||
md_number_to_chars (p, (valueT) *nums, CHARS_PER_LITTLENUM);
|
||||
++nums;
|
||||
size -= CHARS_PER_LITTLENUM;
|
||||
p += CHARS_PER_LITTLENUM;
|
||||
nbytes -= CHARS_PER_LITTLENUM;
|
||||
}
|
||||
|
||||
while (nbytes > 0)
|
||||
{
|
||||
md_number_to_chars (p, extra_digit, CHARS_PER_LITTLENUM);
|
||||
nbytes -= CHARS_PER_LITTLENUM;
|
||||
p += CHARS_PER_LITTLENUM;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
md_number_to_chars (p, (valueT) 0, (int) nbytes);
|
||||
@ -1725,7 +1817,7 @@ emit_expr (exp, nbytes)
|
||||
#define TC_CONS_RELOC 0
|
||||
#endif
|
||||
#endif
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, nbytes, exp, 0,
|
||||
fix_new_exp (frag_now, p - frag_now->fr_literal, (int) nbytes, exp, 0,
|
||||
TC_CONS_RELOC);
|
||||
#endif /* TC_CONS_FIX_NEW */
|
||||
#endif /* BFD_ASSEMBLER */
|
||||
@ -1808,7 +1900,7 @@ parse_bitfield_cons (exp, nbytes)
|
||||
|
||||
if ((width = exp->X_add_number) > (BITS_PER_CHAR * nbytes))
|
||||
{
|
||||
as_warn ("field width %d too big to fit in %d bytes: truncated to %d bits",
|
||||
as_warn ("field width %lu too big to fit in %d bytes: truncated to %d bits",
|
||||
width, nbytes, (BITS_PER_CHAR * nbytes));
|
||||
width = BITS_PER_CHAR * nbytes;
|
||||
} /* too big */
|
||||
@ -1851,6 +1943,7 @@ parse_bitfield_cons (exp, nbytes)
|
||||
|
||||
exp->X_add_number = value;
|
||||
exp->X_op = O_constant;
|
||||
exp->X_unsigned = 1;
|
||||
} /* if looks like a bitfield */
|
||||
} /* parse_bitfield_cons() */
|
||||
|
||||
@ -1952,164 +2045,6 @@ parse_repeat_cons (exp, nbytes)
|
||||
|
||||
#endif /* REPEAT_CONS_EXPRESSIONS */
|
||||
|
||||
/*
|
||||
* big_cons()
|
||||
*
|
||||
* CONStruct more frag(s) of .quads, or .octa etc.
|
||||
* Makes 0 or more new frags.
|
||||
* If need_pass_2 == 1, generate no frag.
|
||||
* This understands only bignums, not expressions. Cons() understands
|
||||
* expressions.
|
||||
*
|
||||
* Constants recognised are '0...'(octal) '0x...'(hex) '...'(decimal).
|
||||
*
|
||||
* This creates objects with struct obstack_control objs, destroying
|
||||
* any context objs held about a partially completed object. Beware!
|
||||
*
|
||||
*
|
||||
* I think it sucks to have 2 different types of integers, with 2
|
||||
* routines to read them, store them etc.
|
||||
* It would be nicer to permit bignums in expressions and only
|
||||
* complain if the result overflowed. However, due to "efficiency"...
|
||||
*/
|
||||
/* Worker to do .quad etc statements. Clobbers input_line_pointer, checks
|
||||
end-of-line. 8=.quad 16=.octa ... */
|
||||
|
||||
void
|
||||
big_cons (nbytes)
|
||||
register int nbytes;
|
||||
{
|
||||
register char c; /* input_line_pointer->c. */
|
||||
register int radix;
|
||||
register long length; /* Number of chars in an object. */
|
||||
register int digit; /* Value of 1 digit. */
|
||||
register int carry; /* For multi-precision arithmetic. */
|
||||
register int work; /* For multi-precision arithmetic. */
|
||||
register char *p; /* For multi-precision arithmetic. */
|
||||
|
||||
extern const char hex_value[]; /* In hex_value.c. */
|
||||
|
||||
/*
|
||||
* The following awkward logic is to parse ZERO or more strings,
|
||||
* comma seperated. Recall an expression includes its leading &
|
||||
* trailing blanks. We fake a leading ',' if there is (supposed to
|
||||
* be) a 1st expression, and keep demanding 1 expression for each ','.
|
||||
*/
|
||||
if (is_it_end_of_statement ())
|
||||
{
|
||||
c = 0; /* Skip loop. */
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ','; /* Do loop. */
|
||||
--input_line_pointer;
|
||||
}
|
||||
while (c == ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
c = *input_line_pointer;
|
||||
/* C contains 1st non-blank character of what we hope is a number. */
|
||||
if (c == '0')
|
||||
{
|
||||
c = *++input_line_pointer;
|
||||
if (c == 'x' || c == 'X')
|
||||
{
|
||||
c = *++input_line_pointer;
|
||||
radix = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
radix = 8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
radix = 10;
|
||||
}
|
||||
/*
|
||||
* This feature (?) is here to stop people worrying about
|
||||
* mysterious zero constants: which is what they get when
|
||||
* they completely omit digits.
|
||||
*/
|
||||
if (hex_value[(unsigned char) c] >= radix)
|
||||
{
|
||||
as_bad ("Missing digits. 0 assumed.");
|
||||
}
|
||||
bignum_high = bignum_low - 1; /* Start constant with 0 chars. */
|
||||
for (;
|
||||
(digit = hex_value[(unsigned char) c]) < radix;
|
||||
c = *++input_line_pointer)
|
||||
{
|
||||
/* Multiply existing number by radix, then add digit. */
|
||||
carry = digit;
|
||||
for (p = bignum_low; p <= bignum_high; p++)
|
||||
{
|
||||
work = (*p & MASK_CHAR) * radix + carry;
|
||||
*p = work & MASK_CHAR;
|
||||
carry = work >> BITS_PER_CHAR;
|
||||
}
|
||||
if (carry)
|
||||
{
|
||||
grow_bignum ();
|
||||
*bignum_high = carry & MASK_CHAR;
|
||||
know ((carry & ~MASK_CHAR) == 0);
|
||||
}
|
||||
}
|
||||
length = bignum_high - bignum_low + 1;
|
||||
if (length > nbytes)
|
||||
{
|
||||
as_warn ("Most significant bits truncated in integer constant.");
|
||||
}
|
||||
else
|
||||
{
|
||||
register long leading_zeroes;
|
||||
|
||||
for (leading_zeroes = nbytes - length;
|
||||
leading_zeroes;
|
||||
leading_zeroes--)
|
||||
{
|
||||
grow_bignum ();
|
||||
*bignum_high = 0;
|
||||
}
|
||||
}
|
||||
if (!need_pass_2)
|
||||
{
|
||||
char *src = bignum_low;
|
||||
p = frag_more (nbytes);
|
||||
if (target_big_endian)
|
||||
{
|
||||
int i;
|
||||
for (i = nbytes - 1; i >= 0; i--)
|
||||
p[i] = *src++;
|
||||
}
|
||||
else
|
||||
memcpy (p, bignum_low, (unsigned int) nbytes);
|
||||
}
|
||||
/* C contains character after number. */
|
||||
SKIP_WHITESPACE ();
|
||||
c = *input_line_pointer;
|
||||
/* C contains 1st non-blank character after number. */
|
||||
}
|
||||
demand_empty_rest_of_line ();
|
||||
} /* big_cons() */
|
||||
|
||||
/* Extend bignum by 1 char. */
|
||||
static void
|
||||
grow_bignum ()
|
||||
{
|
||||
register unsigned long length;
|
||||
|
||||
bignum_high++;
|
||||
if (bignum_high >= bignum_limit)
|
||||
{
|
||||
length = bignum_limit - bignum_low;
|
||||
bignum_low = xrealloc (bignum_low, length + length);
|
||||
bignum_high = bignum_low + length;
|
||||
bignum_limit = bignum_low + length + length;
|
||||
}
|
||||
} /* grow_bignum(); */
|
||||
|
||||
/*
|
||||
* float_cons()
|
||||
*
|
||||
@ -2162,7 +2097,7 @@ float_cons (float_type)
|
||||
err = md_atof (float_type, temp, &length);
|
||||
know (length <= MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT);
|
||||
know (length > 0);
|
||||
if (err && *err)
|
||||
if (err)
|
||||
{
|
||||
as_bad ("Bad floating literal: %s", err);
|
||||
ignore_rest_of_line ();
|
||||
@ -2639,7 +2574,7 @@ s_ignore (arg)
|
||||
|
||||
return;
|
||||
} /* s_ignore() */
|
||||
|
||||
|
||||
/*
|
||||
* Handle .stabX directives, which used to be open-coded.
|
||||
* So much creeping featurism overloaded the semantics that we decided
|
||||
@ -2655,34 +2590,6 @@ s_ignore (arg)
|
||||
* don't need and invent information they need that you didn't supply.
|
||||
*/
|
||||
|
||||
void
|
||||
change_to_section (name, len, exp)
|
||||
char *name;
|
||||
unsigned int len;
|
||||
unsigned int exp;
|
||||
{
|
||||
#ifndef BFD_ASSEMBLER
|
||||
#ifdef MANY_SEGMENTS
|
||||
unsigned int i;
|
||||
extern segment_info_type segment_info[];
|
||||
|
||||
/* Find out if we've already got a section of this name etc */
|
||||
for (i = SEG_E0; i < SEG_E9 && segment_info[i].scnhdr.s_name[0]; i++)
|
||||
{
|
||||
if (strncmp (segment_info[i].scnhdr.s_name, name, len) == 0)
|
||||
{
|
||||
subseg_set (i, exp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* No section, add one */
|
||||
strncpy (segment_info[i].scnhdr.s_name, name, 8);
|
||||
segment_info[i].scnhdr.s_flags = 0 /* STYP_NOLOAD */;
|
||||
subseg_set (i, exp);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Build a string dictionary entry for a .stabX symbol.
|
||||
* The symbol is added to the .<secname>str section.
|
||||
@ -2690,73 +2597,60 @@ change_to_section (name, len, exp)
|
||||
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
|
||||
static unsigned int
|
||||
unsigned int
|
||||
get_stab_string_offset (string, secname)
|
||||
char *string, *secname;
|
||||
const char *string;
|
||||
const char *secname;
|
||||
{
|
||||
segT save_seg;
|
||||
segT seg;
|
||||
subsegT save_subseg;
|
||||
unsigned int length;
|
||||
unsigned int old_gdb_string_index;
|
||||
char *clengthP;
|
||||
int i;
|
||||
char c;
|
||||
/* @@FIXME -- there should be no static data here!
|
||||
This also has the effect of making all stab string tables large enough
|
||||
to contain all the contents written to any of them. This only matters
|
||||
with the Solaris native compiler for the moment, but it should be fixed
|
||||
anyways. */
|
||||
static unsigned int gdb_string_index = 0;
|
||||
unsigned int retval;
|
||||
|
||||
old_gdb_string_index = 0;
|
||||
retval = 0;
|
||||
length = strlen (string);
|
||||
clengthP = (char *) &length;
|
||||
if (length > 0)
|
||||
{ /* Ordinary case. */
|
||||
segT save_seg;
|
||||
subsegT save_subseg;
|
||||
char *newsecname;
|
||||
segT seg;
|
||||
int aligned;
|
||||
char *p;
|
||||
|
||||
save_seg = now_seg;
|
||||
save_subseg = now_subseg;
|
||||
|
||||
/* Create the stabstr sections, if they are not already created. */
|
||||
{
|
||||
char *newsecname = xmalloc (strlen (secname) + 4);
|
||||
strcpy (newsecname, secname);
|
||||
strcat (newsecname, "str");
|
||||
/* Create the stab string section. */
|
||||
newsecname = xmalloc ((unsigned long) (strlen (secname) + 4));
|
||||
strcpy (newsecname, secname);
|
||||
strcat (newsecname, "str");
|
||||
|
||||
seg = subseg_new (newsecname, 0);
|
||||
|
||||
retval = seg_info (seg)->stabu.stab_string_size;
|
||||
if (retval > 0)
|
||||
free (newsecname);
|
||||
else
|
||||
{
|
||||
/* Make sure the first string is empty. */
|
||||
p = frag_more (1);
|
||||
*p = 0;
|
||||
retval = seg_info (seg)->stabu.stab_string_size = 1;
|
||||
#ifdef BFD_ASSEMBLER
|
||||
seg = bfd_get_section_by_name (stdoutput, newsecname);
|
||||
if (seg == 0)
|
||||
{
|
||||
seg = bfd_make_section_old_way (stdoutput, newsecname);
|
||||
bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_ALLOC);
|
||||
}
|
||||
bfd_set_section_flags (stdoutput, seg, SEC_READONLY);
|
||||
#else
|
||||
subseg_new (newsecname, 0);
|
||||
free (newsecname);
|
||||
#endif
|
||||
/* free (newsecname);*/
|
||||
}
|
||||
subseg_set (seg, save_subseg);
|
||||
old_gdb_string_index = gdb_string_index;
|
||||
i = 0;
|
||||
while ((c = *string++))
|
||||
{
|
||||
i++;
|
||||
gdb_string_index++;
|
||||
FRAG_APPEND_1_CHAR (c);
|
||||
}
|
||||
{
|
||||
FRAG_APPEND_1_CHAR ((char) 0);
|
||||
i++;
|
||||
gdb_string_index++;
|
||||
}
|
||||
while (i % 4 != 0)
|
||||
{
|
||||
FRAG_APPEND_1_CHAR ((char) 0);
|
||||
i++;
|
||||
gdb_string_index++;
|
||||
}
|
||||
|
||||
p = frag_more (length + 1);
|
||||
strcpy (p, string);
|
||||
|
||||
seg_info (seg)->stabu.stab_string_size += length + 1;
|
||||
|
||||
subseg_set (save_seg, save_subseg);
|
||||
}
|
||||
return old_gdb_string_index;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* SEPARATE_STAB_SECTIONS */
|
||||
@ -2769,227 +2663,187 @@ s_stab_generic (what, secname)
|
||||
int what;
|
||||
char *secname;
|
||||
{
|
||||
extern int listing;
|
||||
|
||||
symbolS *symbol;
|
||||
char *string;
|
||||
int saved_type = 0;
|
||||
int length;
|
||||
int goof = 0;
|
||||
long longint;
|
||||
segT saved_seg = now_seg;
|
||||
segT seg;
|
||||
subsegT saved_subseg = now_subseg;
|
||||
subsegT subseg;
|
||||
valueT valu;
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
int seg_is_new = 0;
|
||||
#endif
|
||||
char *string;
|
||||
int type;
|
||||
int other;
|
||||
int desc;
|
||||
|
||||
valu = ((char *) obstack_next_free (&frags)) - frag_now->fr_literal;
|
||||
/* The general format is:
|
||||
.stabs "STRING",TYPE,OTHER,DESC,VALUE
|
||||
.stabn TYPE,OTHER,DESC,VALUE
|
||||
.stabd TYPE,OTHER,DESC
|
||||
At this point input_line_pointer points after the pseudo-op and
|
||||
any trailing whitespace. The argument what is one of 's', 'n' or
|
||||
'd' indicating which type of .stab this is. */
|
||||
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
#ifdef BFD_ASSEMBLER
|
||||
seg = bfd_get_section_by_name (stdoutput, secname);
|
||||
if (seg == 0)
|
||||
if (what != 's')
|
||||
string = "";
|
||||
else
|
||||
{
|
||||
seg = subseg_new (secname, 0);
|
||||
bfd_set_section_flags (stdoutput, seg,
|
||||
SEC_READONLY | SEC_ALLOC | SEC_RELOC);
|
||||
subseg_set (saved_seg, subseg);
|
||||
seg_is_new = 1;
|
||||
}
|
||||
#else
|
||||
subseg_new (secname, 0);
|
||||
#endif
|
||||
#endif /* SEPARATE_STAB_SECTIONS */
|
||||
int length;
|
||||
|
||||
/*
|
||||
* Enter with input_line_pointer pointing past .stabX and any following
|
||||
* whitespace.
|
||||
*/
|
||||
if (what == 's')
|
||||
{
|
||||
string = demand_copy_C_string (&length);
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer == ',')
|
||||
input_line_pointer++;
|
||||
else
|
||||
{
|
||||
as_bad ("I need a comma after symbol's name");
|
||||
goof = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
string = "";
|
||||
|
||||
/*
|
||||
* Input_line_pointer->after ','. String->symbol name.
|
||||
*/
|
||||
if (!goof)
|
||||
{
|
||||
#ifdef MAKE_STAB_SYMBOL
|
||||
MAKE_STAB_SYMBOL(symbol, string, secname);
|
||||
#else
|
||||
symbol = symbol_new (string, undefined_section, 0, (struct frag *) 0);
|
||||
#endif
|
||||
/* Make sure that the rest of this is going to work. */
|
||||
if (symbol == NULL)
|
||||
as_fatal ("no stab symbol created");
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case 'd':
|
||||
S_SET_NAME (symbol, NULL); /* .stabd feature. */
|
||||
#ifdef STAB_SYMBOL_SET_VALUE
|
||||
STAB_SYMBOL_SET_VALUE (symbol, valu);
|
||||
#else
|
||||
S_SET_VALUE (symbol, valu);
|
||||
#endif
|
||||
#if STAB_SYMBOL_SET_SEGMENT
|
||||
#else
|
||||
S_SET_SEGMENT (symbol, now_seg);
|
||||
#endif
|
||||
symbol->sy_frag = frag_now;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
symbol->sy_frag = &zero_address_frag;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
symbol->sy_frag = &zero_address_frag;
|
||||
break;
|
||||
|
||||
default:
|
||||
BAD_CASE (what);
|
||||
break;
|
||||
}
|
||||
|
||||
if (get_absolute_expression_and_terminator (&longint) == ',')
|
||||
{
|
||||
saved_type = longint;
|
||||
S_SET_TYPE (symbol, saved_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
as_bad ("I want a comma after the n_type expression");
|
||||
goof = 1;
|
||||
input_line_pointer--; /* Backup over a non-',' char. */
|
||||
as_warn (".stabs: Missing comma");
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!goof)
|
||||
{
|
||||
if (get_absolute_expression_and_terminator (&longint) == ',')
|
||||
S_SET_OTHER (symbol, longint);
|
||||
else
|
||||
{
|
||||
as_bad ("I want a comma after the n_other expression");
|
||||
goof = 1;
|
||||
input_line_pointer--; /* Backup over a non-',' char. */
|
||||
}
|
||||
}
|
||||
|
||||
if (!goof)
|
||||
{
|
||||
S_SET_DESC (symbol, get_absolute_expression ());
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
as_bad ("I want a comma after the n_desc expression");
|
||||
goof = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
input_line_pointer++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Line is messed up - ignore it and get out of here. */
|
||||
if (goof)
|
||||
if (get_absolute_expression_and_terminator (&longint) != ',')
|
||||
{
|
||||
as_warn (".stab%c: Missing comma", what);
|
||||
ignore_rest_of_line ();
|
||||
subseg_set (saved_seg, saved_subseg);
|
||||
return;
|
||||
}
|
||||
type = longint;
|
||||
|
||||
subseg_set (seg, subseg);
|
||||
if (get_absolute_expression_and_terminator (&longint) != ',')
|
||||
{
|
||||
as_warn (".stab%c: Missing comma", what);
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
other = longint;
|
||||
|
||||
#if 0 /* needed for elf only? */
|
||||
if (seg_is_new)
|
||||
/* allocate and discard -- filled in later */
|
||||
(void) frag_more (12);
|
||||
#endif
|
||||
desc = get_absolute_expression ();
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
if (*input_line_pointer != ',')
|
||||
{
|
||||
as_warn (".stab%c: Missing comma", what);
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
input_line_pointer++;
|
||||
SKIP_WHITESPACE ();
|
||||
}
|
||||
|
||||
/* We have not gathered the type, other, and desc information. For
|
||||
.stabs or .stabn, input_line_pointer is now pointing at the
|
||||
value. */
|
||||
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
/* Output the stab information in a separate section. This is used
|
||||
at least for COFF and ELF. */
|
||||
{
|
||||
char *toP;
|
||||
segT saved_seg = now_seg;
|
||||
subsegT saved_subseg = now_subseg;
|
||||
fragS *saved_frag = frag_now;
|
||||
valueT dot;
|
||||
segT seg;
|
||||
unsigned int stroff;
|
||||
char *p;
|
||||
|
||||
dot = frag_now_fix ();
|
||||
|
||||
subseg_new (secname, 0);
|
||||
toP = frag_more (8);
|
||||
/* the string index portion of the stab */
|
||||
md_number_to_chars (toP, (valueT) S_GET_OFFSET_2(symbol), 4);
|
||||
md_number_to_chars (toP + 4, (valueT) S_GET_TYPE(symbol), 1);
|
||||
md_number_to_chars (toP + 5, (valueT) S_GET_OTHER(symbol), 1);
|
||||
md_number_to_chars (toP + 6, (valueT) S_GET_DESC(symbol), 2);
|
||||
}
|
||||
seg = subseg_new (secname, 0);
|
||||
|
||||
if (! seg_info (seg)->hadone)
|
||||
{
|
||||
#ifdef BFD_ASSEMBLER
|
||||
bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_RELOC);
|
||||
#endif
|
||||
#ifdef INIT_STAB_SECTION
|
||||
INIT_STAB_SECTION (seg);
|
||||
#endif
|
||||
seg_info (seg)->hadone = 1;
|
||||
}
|
||||
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
cons (4);
|
||||
input_line_pointer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = frag_more (4);
|
||||
md_number_to_chars (p, 0, 4);
|
||||
}
|
||||
subseg_set (saved_seg, subseg);
|
||||
stroff = get_stab_string_offset (string, secname);
|
||||
|
||||
/* At least for now, stabs in a special stab section are always
|
||||
output as 12 byte blocks of information. */
|
||||
p = frag_more (8);
|
||||
md_number_to_chars (p, (valueT) stroff, 4);
|
||||
md_number_to_chars (p + 4, (valueT) type, 1);
|
||||
md_number_to_chars (p + 5, (valueT) other, 1);
|
||||
md_number_to_chars (p + 6, (valueT) desc, 2);
|
||||
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
/* Pick up the value from the input line. */
|
||||
cons (4);
|
||||
input_line_pointer--;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *fake;
|
||||
symbolS *symbol;
|
||||
expressionS exp;
|
||||
|
||||
/* Arrange for a value representing the current location. */
|
||||
#ifdef DOT_LABEL_PREFIX
|
||||
fake = ".L0\001";
|
||||
#else
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
pseudo_set (symbol);
|
||||
S_SET_TYPE (symbol, saved_type);
|
||||
}
|
||||
fake = "L0\001";
|
||||
#endif
|
||||
symbol = symbol_new (fake, saved_seg, dot, saved_frag);
|
||||
|
||||
exp.X_op = O_symbol;
|
||||
exp.X_add_symbol = symbol;
|
||||
exp.X_add_number = 0;
|
||||
|
||||
emit_expr (&exp, 4);
|
||||
}
|
||||
|
||||
#ifdef OBJ_PROCESS_STAB
|
||||
OBJ_PROCESS_STAB (seg, string, stroff, type, other, desc);
|
||||
#endif
|
||||
|
||||
#if 0 /* for elf only? */
|
||||
if (what == 's' && S_GET_TYPE (symbol) == N_SO)
|
||||
{
|
||||
fragS *fragp = seg_info (seg)->frchainP->frch_root;
|
||||
while (fragp
|
||||
&& fragp->fr_address + fragp->fr_fix < 12)
|
||||
fragp = fragp->fr_next;
|
||||
assert (fragp != 0);
|
||||
assert (fragp->fr_type == rs_fill);
|
||||
assert (fragp->fr_address == 0 && fragp->fr_fix >= 12);
|
||||
md_number_to_chars (fragp->fr_literal, (valueT) symbol->sy_name_offset,
|
||||
4);
|
||||
}
|
||||
#endif
|
||||
subseg_set (saved_seg, saved_subseg);
|
||||
}
|
||||
#else /* ! SEPARATE_STAB_SECTIONS */
|
||||
#ifdef OBJ_PROCESS_STAB
|
||||
OBJ_PROCESS_STAB (what, string, type, other, desc);
|
||||
#else
|
||||
/* Put the stab information in the symbol table. */
|
||||
{
|
||||
symbolS *symbol;
|
||||
|
||||
symbol = symbol_new (string, undefined_section, 0,
|
||||
(struct frag *) NULL);
|
||||
if (what == 's' || what == 'n')
|
||||
{
|
||||
/* Pick up the value from the input line. */
|
||||
symbol->sy_frag = &zero_address_frag;
|
||||
pseudo_set (symbol);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* .stabd sets the name to NULL. Why? */
|
||||
S_SET_NAME (symbol, NULL);
|
||||
symbol->sy_frag = frag_now;
|
||||
S_SET_VALUE (symbol, (valueT) frag_now_fix ());
|
||||
}
|
||||
|
||||
S_SET_TYPE (symbol, type);
|
||||
S_SET_OTHER (symbol, other);
|
||||
S_SET_DESC (symbol, desc);
|
||||
}
|
||||
#endif /* ! OBJ_PROCESS_STAB */
|
||||
#endif /* ! SEPARATE_STAB_SECTIONS */
|
||||
|
||||
#ifndef NO_LISTING
|
||||
if (listing)
|
||||
switch (S_GET_TYPE (symbol))
|
||||
{
|
||||
case N_SLINE:
|
||||
listing_source_line ((unsigned int) S_GET_DESC (symbol));
|
||||
break;
|
||||
case N_SO:
|
||||
case N_SOL:
|
||||
listing_source_file (string);
|
||||
break;
|
||||
}
|
||||
#endif /* !NO_LISTING */
|
||||
|
||||
#ifdef SEPARATE_STAB_SECTIONS
|
||||
subseg_set (saved_seg, saved_subseg);
|
||||
#endif
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case N_SLINE:
|
||||
listing_source_line ((unsigned int) desc);
|
||||
break;
|
||||
case N_SO:
|
||||
case N_SOL:
|
||||
listing_source_file (string);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* ! NO_LISTING */
|
||||
|
||||
demand_empty_rest_of_line ();
|
||||
}
|
||||
|
145
gas/write.c
145
gas/write.c
@ -47,9 +47,12 @@ struct frag *data_last_frag; /* Last frag in segment. */
|
||||
static struct frag *bss_last_frag; /* Last frag in segment. */
|
||||
#endif
|
||||
|
||||
#if ! defined (BFD_ASSEMBLER) && ! defined (BFD)
|
||||
static object_headers headers;
|
||||
long string_byte_count;
|
||||
static char *the_object_file;
|
||||
#endif
|
||||
|
||||
long string_byte_count;
|
||||
char *next_object_file_charP; /* Tracks object file bytes. */
|
||||
|
||||
#ifndef OBJ_VMS
|
||||
@ -69,9 +72,10 @@ static fixS *fix_new_internal PARAMS ((fragS *, int where, int size,
|
||||
offsetT offset, int pcrel,
|
||||
int r_type));
|
||||
#endif
|
||||
#if defined (BFD_ASSEMBLER) || !defined (BFD)
|
||||
static long fixup_segment PARAMS ((fixS * fixP, segT this_segment_type));
|
||||
#endif
|
||||
static relax_addressT relax_align PARAMS ((relax_addressT addr, int align));
|
||||
void relax_segment PARAMS ((struct frag * seg_frag_root, segT seg_type));
|
||||
|
||||
/*
|
||||
* fix_new()
|
||||
@ -234,7 +238,7 @@ append (charPP, fromP, length)
|
||||
if (length == 0)
|
||||
return;
|
||||
|
||||
memcpy (*charPP, fromP, (int) length);
|
||||
memcpy (*charPP, fromP, length);
|
||||
*charPP += length;
|
||||
}
|
||||
|
||||
@ -318,6 +322,8 @@ remove_subsegs (head, seg, root, last)
|
||||
|
||||
#endif /* BFD */
|
||||
|
||||
#if defined (BFD_ASSEMBLER) || !defined (BFD)
|
||||
|
||||
#ifdef BFD_ASSEMBLER
|
||||
static void
|
||||
cvt_frag_to_fill (sec, fragP)
|
||||
@ -391,6 +397,8 @@ cvt_frag_to_fill (headers, fragP)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
|
||||
|
||||
#ifdef BFD_ASSEMBLER
|
||||
static void
|
||||
relax_and_size_seg (abfd, sec, xxx)
|
||||
@ -514,18 +522,27 @@ adjust_reloc_syms (abfd, sec, xxx)
|
||||
if (symsec == &bfd_und_section
|
||||
|| symsec == &bfd_abs_section
|
||||
|| bfd_is_com_section (symsec))
|
||||
continue;
|
||||
{
|
||||
fixp->fx_addsy->sy_used_in_reloc = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Since we're reducing to section symbols, don't attempt to reduce
|
||||
anything that's already using one. */
|
||||
if (sym->bsym == symsec->symbol)
|
||||
continue;
|
||||
{
|
||||
fixp->fx_addsy->sy_used_in_reloc = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Is there some other reason we can't adjust this one? (E.g.,
|
||||
call/bal links in i960-bout symbols.) */
|
||||
#ifdef obj_fix_adjustable
|
||||
if (! obj_fix_adjustable (fixp))
|
||||
continue;
|
||||
{
|
||||
fixp->fx_addsy->sy_used_in_reloc = 1;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
/* If the section symbol isn't going to be output, the relocs
|
||||
at least should still work. If not, figure out what to do
|
||||
@ -545,6 +562,7 @@ adjust_reloc_syms (abfd, sec, xxx)
|
||||
}
|
||||
symseginfo->sym = fixp->fx_addsy;
|
||||
}
|
||||
fixp->fx_addsy->sy_used_in_reloc = 1;
|
||||
}
|
||||
|
||||
dump_section_relocs (abfd, sec, stderr);
|
||||
@ -557,7 +575,8 @@ write_relocs (abfd, sec, xxx)
|
||||
char *xxx;
|
||||
{
|
||||
segment_info_type *seginfo = seg_info (sec);
|
||||
int i, n;
|
||||
int i;
|
||||
unsigned int n;
|
||||
arelent **relocs;
|
||||
fixS *fixp;
|
||||
|
||||
@ -582,7 +601,6 @@ write_relocs (abfd, sec, xxx)
|
||||
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
|
||||
{
|
||||
arelent *reloc;
|
||||
extern arelent *tc_gen_reloc ();
|
||||
char *data;
|
||||
bfd_reloc_status_type s;
|
||||
|
||||
@ -628,7 +646,6 @@ write_relocs (abfd, sec, xxx)
|
||||
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
|
||||
{
|
||||
arelent **reloc;
|
||||
extern arelent **tc_gen_reloc ();
|
||||
char *data;
|
||||
bfd_reloc_status_type s;
|
||||
int j;
|
||||
@ -671,7 +688,8 @@ write_relocs (abfd, sec, xxx)
|
||||
bfd_set_reloc (stdoutput, sec, relocs, n);
|
||||
else
|
||||
bfd_set_section_flags (abfd, sec,
|
||||
bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
|
||||
(bfd_get_section_flags (abfd, sec)
|
||||
& (flagword) ~SEC_RELOC));
|
||||
#ifdef DEBUG2
|
||||
{
|
||||
int i;
|
||||
@ -697,39 +715,39 @@ write_contents (abfd, sec, xxx)
|
||||
{
|
||||
segment_info_type *seginfo = seg_info (sec);
|
||||
unsigned long offset = 0;
|
||||
fragS *frags;
|
||||
fragS *f;
|
||||
|
||||
/* Write out the frags. */
|
||||
if (! (bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
|
||||
return;
|
||||
|
||||
for (frags = seginfo->frchainP->frch_root;
|
||||
frags;
|
||||
frags = frags->fr_next)
|
||||
for (f = seginfo->frchainP->frch_root;
|
||||
f;
|
||||
f = f->fr_next)
|
||||
{
|
||||
int x;
|
||||
unsigned long fill_size;
|
||||
char *fill_literal;
|
||||
long count;
|
||||
|
||||
assert (frags->fr_type == rs_fill);
|
||||
if (frags->fr_fix)
|
||||
assert (f->fr_type == rs_fill);
|
||||
if (f->fr_fix)
|
||||
{
|
||||
x = bfd_set_section_contents (stdoutput, sec,
|
||||
frags->fr_literal, offset,
|
||||
frags->fr_fix);
|
||||
f->fr_literal, (file_ptr) offset,
|
||||
(bfd_size_type) f->fr_fix);
|
||||
assert (x == true);
|
||||
offset += frags->fr_fix;
|
||||
offset += f->fr_fix;
|
||||
}
|
||||
fill_literal = frags->fr_literal + frags->fr_fix;
|
||||
fill_size = frags->fr_var;
|
||||
count = frags->fr_offset;
|
||||
fill_literal = f->fr_literal + f->fr_fix;
|
||||
fill_size = f->fr_var;
|
||||
count = f->fr_offset;
|
||||
assert (count >= 0);
|
||||
if (fill_size && count)
|
||||
while (count--)
|
||||
{
|
||||
x = bfd_set_section_contents (stdoutput, sec,
|
||||
fill_literal, offset,
|
||||
fill_literal, (file_ptr) offset,
|
||||
(bfd_size_type) fill_size);
|
||||
assert (x == true);
|
||||
offset += fill_size;
|
||||
@ -738,7 +756,7 @@ write_contents (abfd, sec, xxx)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BFD_ASSEMBLER) || !defined (BFD)
|
||||
#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
|
||||
static void
|
||||
merge_data_into_text ()
|
||||
{
|
||||
@ -766,7 +784,7 @@ merge_data_into_text ()
|
||||
data_fix_root = NULL;
|
||||
#endif
|
||||
}
|
||||
#endif /* BFD_ASSEMBLER || ! BFD */
|
||||
#endif /* BFD_ASSEMBLER || (! BFD && ! OBJ_AOUT) */
|
||||
|
||||
#if !defined (BFD_ASSEMBLER) && !defined (BFD)
|
||||
static void
|
||||
@ -923,11 +941,7 @@ write_object_file ()
|
||||
#endif
|
||||
for (frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next)
|
||||
{
|
||||
#ifdef BFD_ASSEMBLER
|
||||
subseg_set (frchainP->frch_seg, frchainP->frch_subseg);
|
||||
#else
|
||||
subseg_new (frchainP->frch_seg, frchainP->frch_subseg);
|
||||
#endif
|
||||
frag_align (SUB_SEGMENT_ALIGN (now_seg), NOP_OPCODE);
|
||||
/* frag_align will have left a new frag.
|
||||
Use this last frag for an empty ".fill".
|
||||
@ -1259,7 +1273,8 @@ write_object_file ()
|
||||
/* Set up symbol table, and write it out. */
|
||||
if (symbol_rootP)
|
||||
{
|
||||
int i = 0, n;
|
||||
unsigned int i = 0;
|
||||
unsigned int n;
|
||||
symbolS *symp;
|
||||
|
||||
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
|
||||
@ -1290,27 +1305,30 @@ write_object_file ()
|
||||
symp->bsym->flags,
|
||||
segment_name (symp->bsym->section));
|
||||
#endif
|
||||
{
|
||||
#ifdef obj_frob_symbol
|
||||
if (! symp->sy_used_in_reloc)
|
||||
{
|
||||
int punt = 0;
|
||||
obj_frob_symbol (symp, punt);
|
||||
if (punt)
|
||||
goto punt_it;
|
||||
}
|
||||
#ifdef obj_frob_symbol
|
||||
{
|
||||
int punt = 0;
|
||||
obj_frob_symbol (symp, punt);
|
||||
if (punt)
|
||||
goto punt_it;
|
||||
}
|
||||
#endif
|
||||
#ifdef tc_frob_symbol
|
||||
{
|
||||
int punt = 0;
|
||||
tc_frob_symbol (symp, punt);
|
||||
if (punt)
|
||||
goto punt_it;
|
||||
}
|
||||
{
|
||||
int punt = 0;
|
||||
tc_frob_symbol (symp, punt);
|
||||
if (punt)
|
||||
goto punt_it;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't want to keep this symbol, splice it out of the
|
||||
chain now. */
|
||||
if (S_IS_LOCAL (symp))
|
||||
if (! symp->sy_used_in_reloc
|
||||
&& S_IS_LOCAL (symp))
|
||||
{
|
||||
symbolS *prev, *next;
|
||||
#if defined (obj_frob_symbol) || defined (tc_frob_symbol)
|
||||
@ -1343,6 +1361,14 @@ write_object_file ()
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Make sure we really got a value for the symbol. */
|
||||
if (! symp->sy_resolved)
|
||||
{
|
||||
as_bad ("can't resolve value for symbol \"%s\"",
|
||||
S_GET_NAME (symp));
|
||||
symp->sy_resolved = 1;
|
||||
}
|
||||
|
||||
/* Set the value into the BFD symbol. Up til now the value
|
||||
has only been kept in the gas symbolS struct. */
|
||||
symp->bsym->value = S_GET_VALUE (symp);
|
||||
@ -1506,7 +1532,6 @@ relax_segment (segment_frag_root, segment)
|
||||
symbolS *symbolP;
|
||||
long target;
|
||||
long after;
|
||||
long aim;
|
||||
|
||||
was_address = fragP->fr_address;
|
||||
address = fragP->fr_address += stretch;
|
||||
@ -1552,7 +1577,7 @@ relax_segment (segment_frag_root, segment)
|
||||
if (flagseen['K'])
|
||||
{
|
||||
char buf[50];
|
||||
sprint_value (buf, lie->addnum);
|
||||
sprint_value (buf, (addressT) lie->addnum);
|
||||
as_warn (".word %s-%s+%s didn't fit",
|
||||
S_GET_NAME (lie->add),
|
||||
S_GET_NAME (lie->sub),
|
||||
@ -1623,6 +1648,7 @@ relax_segment (segment_frag_root, segment)
|
||||
const relax_typeS *start_type;
|
||||
relax_substateT next_state;
|
||||
relax_substateT this_state;
|
||||
long aim;
|
||||
|
||||
this_state = fragP->fr_subtype;
|
||||
start_type = this_type = md_relax_table + this_state;
|
||||
@ -1630,6 +1656,7 @@ relax_segment (segment_frag_root, segment)
|
||||
|
||||
if (symbolP)
|
||||
{
|
||||
#ifndef DIFF_EXPR_OK
|
||||
#if !defined (MANY_SEGMENTS) && !defined (BFD_ASSEMBLER)
|
||||
know ((S_GET_SEGMENT (symbolP) == SEG_ABSOLUTE)
|
||||
|| (S_GET_SEGMENT (symbolP) == SEG_DATA)
|
||||
@ -1637,6 +1664,7 @@ relax_segment (segment_frag_root, segment)
|
||||
|| (S_GET_SEGMENT (symbolP) == SEG_TEXT));
|
||||
#endif
|
||||
know (symbolP->sy_frag);
|
||||
#endif
|
||||
know (!(S_GET_SEGMENT (symbolP) == absolute_section)
|
||||
|| symbolP->sy_frag == &zero_address_frag);
|
||||
target +=
|
||||
@ -1733,6 +1761,8 @@ relax_segment (segment_frag_root, segment)
|
||||
*/
|
||||
} /* relax_segment() */
|
||||
|
||||
#if defined (BFD_ASSEMBLER) || !defined (BFD)
|
||||
|
||||
/* fixup_segment()
|
||||
|
||||
Go through all the fixS's in a segment and see which ones can be
|
||||
@ -1806,6 +1836,7 @@ fixup_segment (fixP, this_segment_type)
|
||||
if (!add_symbolP)
|
||||
{
|
||||
/* Its just -sym */
|
||||
/* @@ Should try converting to pcrel ref to fixed addr. */
|
||||
if (S_GET_SEGMENT (sub_symbolP) != absolute_section)
|
||||
as_bad ("Negative of non-absolute symbol %s",
|
||||
S_GET_NAME (sub_symbolP));
|
||||
@ -1843,6 +1874,19 @@ fixup_segment (fixP, this_segment_type)
|
||||
{
|
||||
add_number -= S_GET_VALUE (sub_symbolP);
|
||||
}
|
||||
#ifdef DIFF_EXPR_OK
|
||||
else if (!pcrel
|
||||
&& S_GET_SEGMENT (sub_symbolP) == this_segment_type)
|
||||
{
|
||||
/* Make it pc-relative. */
|
||||
add_number += (md_pcrel_from (fixP)
|
||||
- S_GET_VALUE (sub_symbolP));
|
||||
pcrel = 1;
|
||||
fixP->fx_pcrel = 1;
|
||||
sub_symbolP = 0;
|
||||
fixP->fx_subsy = 0;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
char buf[50];
|
||||
@ -1961,8 +2005,9 @@ fixup_segment (fixP, this_segment_type)
|
||||
if (!flagseen['J']
|
||||
&& size == 2
|
||||
&& add_number > 0x7fff)
|
||||
as_bad ("Signed .word overflow; switch may be too large; %d at 0x%x",
|
||||
add_number, fragP->fr_address + where);
|
||||
as_bad ("Signed .word overflow; switch may be too large; %ld at 0x%lx",
|
||||
(long) add_number,
|
||||
(unsigned long) (fragP->fr_address + where));
|
||||
#endif
|
||||
} /* not a bit fix */
|
||||
|
||||
@ -1987,4 +2032,6 @@ fixup_segment (fixP, this_segment_type)
|
||||
return (seg_reloc_count);
|
||||
}
|
||||
|
||||
#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
|
||||
|
||||
/* end of write.c */
|
||||
|
Loading…
Reference in New Issue
Block a user