+/* Resolve the value of a symbol. This is called during the final
+ pass over the symbol table to resolve any symbols with complex
+ values. */
+
+void
+resolve_symbol_value (symp)
+ symbolS *symp;
+{
+ if (symp->sy_resolved)
+ return;
+
+ if (symp->sy_resolving)
+ {
+ as_bad ("Symbol definition loop encountered at %s",
+ S_GET_NAME (symp));
+ S_SET_VALUE (symp, (valueT) 0);
+ }
+ else
+ {
+ symp->sy_resolving = 1;
+
+ if (symp->sy_value.X_seg == absolute_section)
+ S_SET_VALUE (symp, S_GET_VALUE (symp) + symp->sy_frag->fr_address);
+ else if (symp->sy_value.X_seg == undefined_section)
+ {
+ resolve_symbol_value (symp->sy_value.X_add_symbol);
+
+#ifdef obj_frob_forward_symbol
+ /* Some object formats need to forward the segment. */
+ obj_frob_forward_symbol (symp);
+#endif
+
+ S_SET_VALUE (symp,
+ (symp->sy_value.X_add_number
+ + symp->sy_frag->fr_address
+ + S_GET_VALUE (symp->sy_value.X_add_symbol)));
+ }
+ else
+ {
+ /* More cases need to be added here. */
+ abort ();
+ }
+ }
+
+ symp->sy_resolved = 1;
+}
+