aboutsummaryrefslogtreecommitdiff
path: root/bfd/aoutx.h
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1994-01-18 21:46:46 +0000
committerIan Lance Taylor <ian@airs.com>1994-01-18 21:46:46 +0000
commit53155af199a516be8cc26189cbf80064f640f8e0 (patch)
tree8c3c2b900a093acabe23149156d78c84fe91c3b6 /bfd/aoutx.h
parentc6e0f918e231d428ab51b5009096789d8d66bc47 (diff)
downloadgdb-53155af199a516be8cc26189cbf80064f640f8e0.zip
gdb-53155af199a516be8cc26189cbf80064f640f8e0.tar.gz
gdb-53155af199a516be8cc26189cbf80064f640f8e0.tar.bz2
* aoutx.h (aout_link_add_symbols): Increment sym_hash as well as p
for an indirect or warning symbol. (aout_link_write_symbols): Update sym_hash with the target of an indirect symbol. If an indirect symbol is defined, output the calculated value and don't output the target symbol.
Diffstat (limited to 'bfd/aoutx.h')
-rw-r--r--bfd/aoutx.h71
1 files changed, 61 insertions, 10 deletions
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 59137a0..1e612f3 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -3041,7 +3041,10 @@ aout_link_add_symbols (abfd, info)
which is the symbol to indirect to (actually, an N_INDR
symbol without N_EXT set is pretty useless). */
if (type == N_INDR)
- ++p;
+ {
+ ++p;
+ ++sym_hash;
+ }
continue;
}
@@ -3125,6 +3128,9 @@ aout_link_add_symbols (abfd, info)
(info, abfd, name, flags, section, value, string, copy, false,
ARCH_SIZE, (struct bfd_link_hash_entry **) sym_hash)))
return false;
+
+ if (type == (N_INDR | N_EXT) || type == N_WARNING)
+ ++sym_hash;
}
return true;
@@ -3401,6 +3407,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
struct external_nlist *sym_end;
struct aout_link_hash_entry **sym_hash;
boolean pass;
+ boolean skip_indirect;
output_bfd = finfo->output_bfd;
sym_count = obj_aout_external_sym_count (input_bfd);
@@ -3434,6 +3441,7 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
}
pass = false;
+ skip_indirect = false;
sym = obj_aout_external_syms (input_bfd);
sym_end = sym + sym_count;
sym_hash = obj_aout_sym_hashes (input_bfd);
@@ -3452,13 +3460,23 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
if (pass)
{
- /* Pass this symbol through. */
+ /* Pass this symbol through. It is the target of an
+ indirect or warning symbol. */
val = GET_WORD (input_bfd, sym->e_value);
pass = false;
}
+ else if (skip_indirect)
+ {
+ /* Skip this symbol, which is the target of an indirect
+ symbol that we have changed to no longer be an indirect
+ symbol. */
+ skip_indirect = false;
+ continue;
+ }
else
{
struct aout_link_hash_entry *h;
+ struct aout_link_hash_entry *hresolve;
/* We have saved the hash table entry for this symbol, if
there is one. Note that we could just look it up again
@@ -3466,6 +3484,20 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
external symbol. */
h = *sym_hash;
+ /* If this is an indirect symbol, then change hresolve to
+ the base symbol. We also change sym_hash so that the
+ relocation routines relocate against the real symbol. */
+ hresolve = h;
+ if (h != (struct aout_link_hash_entry *) NULL
+ && h->root.type == bfd_link_hash_indirect)
+ {
+ hresolve = (struct aout_link_hash_entry *) h->root.u.i.link;
+ while (hresolve->root.type == bfd_link_hash_indirect)
+ hresolve = ((struct aout_link_hash_entry *)
+ hresolve->root.u.i.link);
+ *sym_hash = hresolve;
+ }
+
/* If the symbol has already been written out, skip it. */
if (h != (struct aout_link_hash_entry *) NULL
&& h->root.written)
@@ -3509,10 +3541,17 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
symsec = obj_bsssec (input_bfd);
else if ((type & N_TYPE) == N_ABS)
symsec = &bfd_abs_section;
- else if ((type & N_TYPE) == N_INDR
+ else if (((type & N_TYPE) == N_INDR
+ && (hresolve == (struct aout_link_hash_entry *) NULL
+ || (hresolve->root.type != bfd_link_hash_defined
+ && hresolve->root.type != bfd_link_hash_common)))
|| type == N_WARNING)
{
- /* Pass the next symbol through unchanged. */
+ /* Pass the next symbol through unchanged. The
+ condition above for indirect symbols is so that if
+ the indirect symbol was defined, we output it with
+ the correct definition so the debugger will
+ understand it. */
pass = true;
val = GET_WORD (input_bfd, sym->e_value);
symsec = NULL;
@@ -3524,20 +3563,32 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
}
else
{
+ /* If we get here with an indirect symbol, it means that
+ we are outputting it with a real definition. In such
+ a case we do not want to output the next symbol,
+ which is the target of the indirection. */
+ if ((type & N_TYPE) == N_INDR)
+ skip_indirect = true;
+
+ /* We need to get the value from the hash table. We use
+ hresolve so that if we have defined an indirect
+ symbol we output the final definition. */
if (h == (struct aout_link_hash_entry *) NULL)
val = 0;
- else if (h->root.type == bfd_link_hash_defined)
+ else if (hresolve->root.type == bfd_link_hash_defined)
{
+ asection *input_section;
asection *output_section;
/* This case means a common symbol which was turned
into a defined symbol. */
- output_section = h->root.u.def.section->output_section;
+ input_section = hresolve->root.u.def.section;
+ output_section = input_section->output_section;
BFD_ASSERT (output_section == &bfd_abs_section
|| output_section->owner == output_bfd);
- val = (h->root.u.def.value
+ val = (hresolve->root.u.def.value
+ bfd_get_section_vma (output_bfd, output_section)
- + h->root.u.def.section->output_offset);
+ + input_section->output_offset);
/* Get the correct type based on the section. If
this is a constructed set, force it to be
@@ -3559,8 +3610,8 @@ aout_link_write_symbols (finfo, input_bfd, symbol_map)
else
type |= N_ABS;
}
- else if (h->root.type == bfd_link_hash_common)
- val = h->root.u.c.size;
+ else if (hresolve->root.type == bfd_link_hash_common)
+ val = hresolve->root.u.c.size;
else
val = 0;