* 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.
+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.
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;
{"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},
{"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},
{
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);
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)
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;
}
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);
}
}
- subseg_new ((char *) save_seg->name, save_subseg);
+ subseg_set (save_seg, save_subseg);
}
#else
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);
}
}
- subseg_new (save_seg, save_subseg);
+ subseg_set (save_seg, save_subseg);
}
}
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;
seg,
SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC | SEC_LOAD);
- subseg_new(save_seg->name, save_subseg);
+ subseg_set(save_seg, save_subseg);
}
#endif
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;
void
pa_align_subseg (seg, subseg)
-#ifdef OBJ_SOM
segT seg;
-#else
- asection *seg;
-#endif
subsegT subseg;
{
subspace_dict_chainS *now_subspace;
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;
}
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;
}
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);
}
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 ();
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 ();
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);
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;
}
void
pa_data ()
{
- s_data ();
+ s_data (0);
pa_undefine_label ();
}
void
pa_fill ()
{
- s_fill ();
+ s_fill (0);
pa_undefine_label ();
}
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 ();
}
/* now, switch back to the original segment */
- subseg_new(save_seg->name, save_subseg);
+ subseg_set(save_seg, save_subseg);
return;
}
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);
}
}
{"sysproc", parse_po, S_SYSPROC},
{"word", cons, 4},
- {"quad", big_cons, 16},
+ {"quad", cons, 16},
{0, 0, 0}
};
{
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
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
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
};
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"))
/* 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++;
}
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
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;
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 */
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;
\f
void
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;
{"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 */
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 */
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"))
{
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"))
{
*
* 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 (?)
*
{
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)
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;
}
}
#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;
/* 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);
#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 */
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 */
exp->X_add_number = value;
exp->X_op = O_constant;
+ exp->X_unsigned = 1;
} /* if looks like a bitfield */
} /* parse_bitfield_cons() */
#endif /* REPEAT_CONS_EXPRESSIONS */
\f
-/*
- * 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(); */
-\f
/*
* float_cons()
*
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 ();
return;
} /* s_ignore() */
-
+\f
/*
* Handle .stabX directives, which used to be open-coded.
* So much creeping featurism overloaded the semantics that we decided
* 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.
#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;
-
- old_gdb_string_index = 0;
+ unsigned int retval;
+
+ 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 */
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
-
- valu = ((char *) obstack_next_free (&frags)) - frag_now->fr_literal;
-
-#ifdef SEPARATE_STAB_SECTIONS
-#ifdef BFD_ASSEMBLER
- seg = bfd_get_section_by_name (stdoutput, secname);
- if (seg == 0)
+ char *string;
+ int type;
+ int other;
+ int desc;
+
+ /* 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. */
+
+ 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;
+ as_warn (".stabs: Missing comma");
+ ignore_rest_of_line ();
+ return;
}
}
- else
- string = "";
- /*
- * Input_line_pointer->after ','. String->symbol name.
- */
- if (!goof)
+ if (get_absolute_expression_and_terminator (&longint) != ',')
{
-#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 (".stab%c: Missing comma", what);
+ ignore_rest_of_line ();
+ return;
}
+ type = longint;
- if (!goof)
+ if (get_absolute_expression_and_terminator (&longint) != ',')
{
- 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. */
- }
+ as_warn (".stab%c: Missing comma", what);
+ ignore_rest_of_line ();
+ return;
}
+ other = longint;
- if (!goof)
+ desc = get_absolute_expression ();
+ if (what == 's' || what == 'n')
{
- S_SET_DESC (symbol, get_absolute_expression ());
- if (what == 's' || what == 'n')
+ if (*input_line_pointer != ',')
{
- if (*input_line_pointer != ',')
- {
- as_bad ("I want a comma after the n_desc expression");
- goof = 1;
- }
- else
- {
- input_line_pointer++;
- }
+ as_warn (".stab%c: Missing comma", what);
+ ignore_rest_of_line ();
+ return;
}
+ input_line_pointer++;
+ SKIP_WHITESPACE ();
}
- /* Line is messed up - ignore it and get out of here. */
- if (goof)
- {
- ignore_rest_of_line ();
- subseg_set (saved_seg, saved_subseg);
- return;
- }
-
- subseg_set (seg, subseg);
-
-#if 0 /* needed for elf only? */
- if (seg_is_new)
- /* allocate and discard -- filled in later */
- (void) frag_more (12);
-#endif
+ /* 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;
-
- 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);
- }
+ 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 ();
+
+ 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);
-#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);
- }
+ 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
-#ifndef NO_LISTING
- if (listing)
- switch (S_GET_TYPE (symbol))
+ 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
{
- case N_SLINE:
- listing_source_line ((unsigned int) S_GET_DESC (symbol));
- break;
- case N_SO:
- case N_SOL:
- listing_source_file (string);
- break;
+ /* .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 ());
}
-#endif /* !NO_LISTING */
-#ifdef SEPARATE_STAB_SECTIONS
- subseg_set (saved_seg, saved_subseg);
-#endif
+ 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 (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 ();
}
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
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()
if (length == 0)
return;
- memcpy (*charPP, fromP, (int) length);
+ memcpy (*charPP, fromP, length);
*charPP += length;
}
#endif /* BFD */
+#if defined (BFD_ASSEMBLER) || !defined (BFD)
+
#ifdef BFD_ASSEMBLER
static void
cvt_frag_to_fill (sec, fragP)
}
}
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
#ifdef BFD_ASSEMBLER
static void
relax_and_size_seg (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
}
symseginfo->sym = fixp->fx_addsy;
}
+ fixp->fx_addsy->sy_used_in_reloc = 1;
}
dump_section_relocs (abfd, sec, stderr);
char *xxx;
{
segment_info_type *seginfo = seg_info (sec);
- int i, n;
+ int i;
+ unsigned int n;
arelent **relocs;
fixS *fixp;
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;
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;
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;
{
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;
}
#endif
-#if defined(BFD_ASSEMBLER) || !defined (BFD)
+#if defined(BFD_ASSEMBLER) || (!defined (BFD) && !defined(OBJ_AOUT))
static void
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
#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".
/* 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))
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)
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);
symbolS *symbolP;
long target;
long after;
- long aim;
was_address = fragP->fr_address;
address = fragP->fr_address += stretch;
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),
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;
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)
|| (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 +=
*/
} /* 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
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));
{
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];
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 */
return (seg_reloc_count);
}
+#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */
+
/* end of write.c */