2009-10-09 Doug Kwan <dougkwan@google.com>
[deliverable/binutils-gdb.git] / gold / symtab.cc
index 562e1fc43adfe41a881ec45124a03cf3c39ae599..8a9e6f103ae4392dc670b27ae119e46bbf141909 100644 (file)
@@ -2355,30 +2355,17 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool,
   return off;
 }
 
-// Finalize the symbol SYM.  This returns true if the symbol should be
-// added to the symbol table, false otherwise.
+// Compute the final value of SYM and store status in location PSTATUS.
+// During relaxation, this may be called multiple times for a symbol to
+// compute its would-be final value in each relaxation pass.
 
 template<int size>
-bool
-Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
+typename Sized_symbol<size>::Value_type
+Symbol_table::compute_final_value(
+    const Sized_symbol<size>* sym,
+    Compute_final_value_status* pstatus) const
 {
   typedef typename Sized_symbol<size>::Value_type Value_type;
-
-  Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(unsized_sym);
-
-  // The default version of a symbol may appear twice in the symbol
-  // table.  We only need to finalize it once.
-  if (sym->has_symtab_index())
-    return false;
-
-  if (!sym->in_reg())
-    {
-      gold_assert(!sym->has_symtab_index());
-      sym->set_symtab_index(-1U);
-      gold_assert(sym->dynsym_index() == -1U);
-      return false;
-    }
-
   Value_type value;
 
   switch (sym->source())
@@ -2392,9 +2379,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
            && shndx != elfcpp::SHN_ABS
            && !Symbol::is_common_shndx(shndx))
          {
-           gold_error(_("%s: unsupported symbol section 0x%x"),
-                      sym->demangled_name().c_str(), shndx);
-           shndx = elfcpp::SHN_UNDEF;
+           *pstatus = CFVS_UNSUPPORTED_SYMBOL_SECTION;
+           return 0;
          }
 
        Object* symobj = sym->object();
@@ -2435,12 +2421,12 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
 
            if (os == NULL)
              {
-               sym->set_symtab_index(-1U);
                 bool static_or_reloc = (parameters->doing_static_link() ||
                                         parameters->options().relocatable());
                 gold_assert(static_or_reloc || sym->dynsym_index() == -1U);
 
-               return false;
+               *pstatus = CFVS_NO_OUTPUT_SECTION;
+               return 0;
              }
 
             if (secoff64 == -1ULL)
@@ -2513,6 +2499,57 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
       gold_unreachable();
     }
 
+  *pstatus = CFVS_OK;
+  return value;
+}
+
+// Finalize the symbol SYM.  This returns true if the symbol should be
+// added to the symbol table, false otherwise.
+
+template<int size>
+bool
+Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
+{
+  typedef typename Sized_symbol<size>::Value_type Value_type;
+
+  Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(unsized_sym);
+
+  // The default version of a symbol may appear twice in the symbol
+  // table.  We only need to finalize it once.
+  if (sym->has_symtab_index())
+    return false;
+
+  if (!sym->in_reg())
+    {
+      gold_assert(!sym->has_symtab_index());
+      sym->set_symtab_index(-1U);
+      gold_assert(sym->dynsym_index() == -1U);
+      return false;
+    }
+
+  // Compute final symbol value.
+  Compute_final_value_status status;
+  Value_type value = this->compute_final_value(sym, &status);
+
+  switch (status)
+    {
+    case CFVS_OK:
+      break;
+    case CFVS_UNSUPPORTED_SYMBOL_SECTION:
+      {
+       bool is_ordinary;
+       unsigned int shndx = sym->shndx(&is_ordinary);
+       gold_error(_("%s: unsupported symbol section 0x%x"),
+                  sym->demangled_name().c_str(), shndx);
+      }
+      break;
+    case CFVS_NO_OUTPUT_SECTION:
+      sym->set_symtab_index(-1U);
+      return false;
+    default:
+      gold_unreachable();
+    }
+
   sym->set_value(value);
 
   if (parameters->options().strip_all()
This page took 0.024228 seconds and 4 git commands to generate.