This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
reducing reloc syms to section syms
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Tue, 7 May 2002 17:09:55 +0930
- Subject: reducing reloc syms to section syms
Is there any benefit in reducing just some relocs using a given symbol
to the section symbol, and not others? To keep things consistent,
and help out a certain kernel hacker doing nasty things to object
files, I'd like to propose this patch. Comments?
gas/ChangeLog
* write.c (mark_reloc_syms): Split out from..
(adjust_reloc_syms): ..here.
(write_object_file): Call mark_reloc_syms.
Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.54
diff -u -p -r1.54 write.c
--- gas/write.c 1 May 2002 00:33:09 -0000 1.54
+++ gas/write.c 7 May 2002 07:22:50 -0000
@@ -129,6 +129,7 @@ static fragS *chain_frchains_together_1
#ifdef BFD_ASSEMBLER
static void chain_frchains_together PARAMS ((bfd *, segT, PTR));
static void cvt_frag_to_fill PARAMS ((segT, fragS *));
+static void mark_reloc_syms PARAMS ((bfd *, asection *, PTR));
static void adjust_reloc_syms PARAMS ((bfd *, asection *, PTR));
static void write_relocs PARAMS ((bfd *, asection *, PTR));
static void write_contents PARAMS ((bfd *, asection *, PTR));
@@ -729,7 +730,7 @@ dump_section_relocs (abfd, sec, stream_)
#endif
static void
-adjust_reloc_syms (abfd, sec, xxx)
+mark_reloc_syms (abfd, sec, xxx)
bfd *abfd ATTRIBUTE_UNUSED;
asection *sec;
PTR xxx ATTRIBUTE_UNUSED;
@@ -752,7 +753,7 @@ adjust_reloc_syms (abfd, sec, xxx)
asection *symsec;
#ifdef DEBUG5
- fprintf (stderr, "\n\nadjusting fixup:\n");
+ fprintf (stderr, "\n\nmarking fixup:\n");
print_fixup (fixp);
#endif
@@ -780,7 +781,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (sym != NULL && symbol_mri_common_p (sym))
{
/* These symbols are handled specially in fixup_segment. */
- goto done;
+ continue;
}
symsec = S_GET_SEGMENT (sym);
@@ -800,7 +801,7 @@ adjust_reloc_syms (abfd, sec, xxx)
symbol_mark_used_in_reloc (fixp->fx_subsy);
#endif
}
- goto done;
+ continue;
}
/* If it's one of these sections, assume the symbol is
@@ -819,7 +820,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (fixp->fx_subsy)
symbol_mark_used_in_reloc (fixp->fx_subsy);
#endif
- goto done;
+ continue;
}
/* Don't try to reduce relocs which refer to non-local symbols
@@ -852,7 +853,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (fixp->fx_subsy != NULL)
symbol_mark_used_in_reloc (fixp->fx_subsy);
#endif
- goto done;
+ continue;
}
}
@@ -861,7 +862,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (symbol_section_p (sym))
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
- goto done;
+ continue;
}
#ifdef BFD_ASSEMBLER
@@ -872,7 +873,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (S_IS_WEAK (sym))
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
- goto done;
+ continue;
}
/* Never adjust a reloc against local symbol in a merge section
@@ -880,7 +881,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if ((symsec->flags & SEC_MERGE) && fixp->fx_offset)
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
- goto done;
+ continue;
}
#endif
@@ -890,7 +891,7 @@ adjust_reloc_syms (abfd, sec, xxx)
if (! obj_fix_adjustable (fixp))
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
- goto done;
+ continue;
}
#endif
@@ -901,42 +902,62 @@ adjust_reloc_syms (abfd, sec, xxx)
if (! tc_fix_adjustable (fixp))
{
symbol_mark_used_in_reloc (fixp->fx_addsy);
- goto done;
+ 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
- when we run into that case.
-
- We refetch the segment when calling section_symbol, rather
- than using symsec, because S_GET_VALUE may wind up changing
- the section when it calls resolve_symbol_value. */
- fixp->fx_offset += S_GET_VALUE (sym);
- fixp->fx_addsy = section_symbol (S_GET_SEGMENT (sym));
- symbol_mark_used_in_reloc (fixp->fx_addsy);
-#ifdef DEBUG5
- fprintf (stderr, "\nadjusted fixup:\n");
- print_fixup (fixp);
-#endif
-
- done:
- ;
}
-#if 1 /* def RELOC_REQUIRES_SYMBOL */
else
{
/* There was no symbol required by this relocation. However,
BFD doesn't really handle relocations without symbols well.
(At least, the COFF support doesn't.) So for now we fake up
- a local symbol in the absolute section. */
+ a local symbol in the absolute section.
+ Don't symbol_mark_used_in_reloc here; the absolute section
+ sym is read-only. */
fixp->fx_addsy = section_symbol (absolute_section);
-#if 0
- fixp->fx_addsy->sy_used_in_reloc = 1;
-#endif
}
+}
+
+static void
+adjust_reloc_syms (abfd, sec, xxx)
+ bfd *abfd ATTRIBUTE_UNUSED;
+ asection *sec;
+ PTR xxx ATTRIBUTE_UNUSED;
+{
+ segment_info_type *seginfo = seg_info (sec);
+ fixS *fixp;
+
+ if (seginfo == NULL)
+ return;
+
+ for (fixp = seginfo->fix_root; fixp; fixp = fixp->fx_next)
+ if (!fixp->fx_done)
+ {
+ symbolS *sym;
+ asection *symsec;
+
+ sym = fixp->fx_addsy;
+ if (symbol_mri_common_p (sym))
+ continue;
+
+ symsec = S_GET_SEGMENT (sym);
+ if (bfd_is_abs_section (symsec)
+ || bfd_is_und_section (symsec)
+ || bfd_is_com_section (symsec))
+ continue;
+
+ if (symbol_used_in_reloc_p (sym))
+ continue;
+
+ fixp->fx_offset += S_GET_VALUE (sym);
+ fixp->fx_addsy = section_symbol (symsec);
+ symbol_mark_used_in_reloc (fixp->fx_addsy);
+#ifdef DEBUG5
+ fprintf (stderr, "\nadjusted fixup:\n");
+ print_fixup (fixp);
#endif
+ }
dump_section_relocs (abfd, sec, stderr);
}
@@ -1916,6 +1937,7 @@ write_object_file ()
obj_frob_file_before_adjust ();
#endif
+ bfd_map_over_sections (stdoutput, mark_reloc_syms, (char *) 0);
bfd_map_over_sections (stdoutput, adjust_reloc_syms, (char *) 0);
/* Set up symbol table, and write it out. */
--
Alan Modra
IBM OzLabs - Linux Technology Centre