/* write.c - emit .o file
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2021 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
RELOC_ENUM r_type /* Relocation type. */)
{
return fix_new_internal (frag, where, size, add_symbol,
- (symbolS *) NULL, offset, pcrel, r_type, FALSE);
+ (symbolS *) NULL, offset, pcrel, r_type, false);
}
/* Create a fixup for an expression. Currently we only support fixups
}
return fix_new_internal (frag, where, size, add, sub, off, pcrel,
- r_type, FALSE);
+ r_type, false);
}
/* Create a fixup at the beginning of FRAG. The arguments are the same
offsetT offset, int pcrel, RELOC_ENUM r_type)
{
return fix_new_internal (frag, 0, size, add_symbol,
- (symbolS *) NULL, offset, pcrel, r_type, TRUE);
+ (symbolS *) NULL, offset, pcrel, r_type, true);
}
/* Generic function to determine whether a fixup requires a relocation. */
prevent the offset from overflowing the relocated field,
unless it has enough bits to cover the whole address
space. */
- if (S_IS_LOCAL (sym) && !symbol_section_p (sym)
+ if (S_IS_LOCAL (sym)
+ && S_IS_DEFINED (sym)
+ && !symbol_section_p (sym)
&& (sec->use_rela_p
|| (howto->partial_inplace
&& (!howto->pc_relative
}
}
-static bfd_boolean
-is_dwo_section (asection *sec)
-{
- const char *name;
- int len;
-
- if (sec == NULL || (name = bfd_section_name (sec)) == NULL)
- return FALSE;
-
- len = strlen (name);
- if (len < 5)
- return FALSE;
-
- return strncmp (name + len - 4, ".dwo", 4) == 0;
-}
-
/* This pass over fixups decides whether symbols can be replaced with
section symbols. */
/* Since we're reducing to section symbols, don't attempt to reduce
anything that's already using one. */
if (symbol_section_p (sym))
- continue;
+ {
+ /* Mark the section symbol used in relocation so that it will
+ be included in the symbol table. */
+ symbol_mark_used_in_reloc (sym);
+ continue;
+ }
symsec = S_GET_SEGMENT (sym);
if (symsec == NULL)
/* The GNU toolchain uses an extension for ELF: a
section beginning with the magic string
.gnu.linkonce is a linkonce section. */
- && strncmp (segment_name (symsec), ".gnu.linkonce",
- sizeof ".gnu.linkonce" - 1) == 0))
+ && startswith (segment_name (symsec), ".gnu.linkonce")))
continue;
}
#endif
}
- /* PR 26841: DWO sections are not supposed to have relocations. */
- if (is_dwo_section (sec) && seginfo->fix_root != NULL)
- {
- as_bad (_("DWO section '%s' contains unresolved expressions - this is not allowed"),
- bfd_section_name (sec));
- seginfo->fix_root = NULL; /* FIXME: Memory leak ? */
- }
-
dump_section_relocs (abfd, sec, stderr);
}
{
valueT add_number;
fragS *fragP;
- segT add_symbol_segment = absolute_section;
if (fixP != NULL && abs_section_sym == NULL)
abs_section_sym = section_symbol (absolute_section);
for (; fixP; fixP = fixP->fx_next)
{
+ segT add_symbol_segment = absolute_section;
+
#ifdef DEBUG5
fprintf (stderr, "\nprocessing fixup:\n");
print_fixup (fixP);
mask = 0;
mask--; /* Set all bits to one. */
mask <<= fixP->fx_size * 8 - (fixP->fx_signed ? 1 : 0);
- if ((add_number & mask) != 0 && (add_number & mask) != mask)
+ if ((add_number & mask) != 0
+ && (fixP->fx_signed
+ ? (add_number & mask) != mask
+ : (-add_number & mask) != 0))
{
char buf[50], buf2[50];
- sprint_value (buf, fragP->fr_address + fixP->fx_where);
+ bfd_sprintf_vma (stdoutput, buf, fragP->fr_address + fixP->fx_where);
if (add_number > 1000)
- sprint_value (buf2, add_number);
+ bfd_sprintf_vma (stdoutput, buf2, add_number);
else
sprintf (buf2, "%ld", (long) add_number);
as_bad_where (fixP->fx_file, fixP->fx_line,
return;
section_name = bfd_section_name (sec);
- if (strncmp (section_name, ".debug_", 7) != 0)
+ if (!startswith (section_name, ".debug_"))
return;
strm = compress_init ();
int nsyms;
asymbol **asympp;
symbolS *symp;
- bfd_boolean result;
+ bool result;
/* Count symbols. We can't rely on a count made by the loop in
write_object_file, because *_frob_file may add a new symbol or
- two. */
+ two. Generate unused section symbols only if needed. */
nsyms = 0;
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
- nsyms++;
+ if (bfd_keep_unused_section_symbols (stdoutput)
+ || !symbol_section_p (symp)
+ || symbol_used_in_reloc_p (symp))
+ nsyms++;
if (nsyms)
{
asympp = (asymbol **) bfd_alloc (stdoutput, amt);
symp = symbol_rootP;
- for (i = 0; i < nsyms; i++, symp = symbol_next (symp))
- {
- asympp[i] = symbol_get_bfdsym (symp);
- if (asympp[i]->flags != BSF_SECTION_SYM
- || !(bfd_is_const_section (asympp[i]->section)
- && asympp[i]->section->symbol == asympp[i]))
- asympp[i]->flags |= BSF_KEEP;
- symbol_mark_written (symp);
- }
+ for (i = 0; i < nsyms; symp = symbol_next (symp))
+ if (bfd_keep_unused_section_symbols (stdoutput)
+ || !symbol_section_p (symp)
+ || symbol_used_in_reloc_p (symp))
+ {
+ asympp[i] = symbol_get_bfdsym (symp);
+ if (asympp[i]->flags != BSF_SECTION_SYM
+ || !(bfd_is_const_section (asympp[i]->section)
+ && asympp[i]->section->symbol == asympp[i]))
+ asympp[i]->flags |= BSF_KEEP;
+ symbol_mark_written (symp);
+ /* Include this section symbol in the symbol table. */
+ if (symbol_section_p (symp))
+ asympp[i]->flags |= BSF_SECTION_SYM_USED;
+ i++;
+ }
}
else
asympp = 0;
return;
/* Create a GNU Build Attribute section. */
- sec = subseg_new (GNU_BUILD_ATTRS_SECTION_NAME, FALSE);
+ sec = subseg_new (GNU_BUILD_ATTRS_SECTION_NAME, false);
elf_section_type (sec) = SHT_NOTE;
bfd_set_section_flags (sec, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA
| SEC_OCTETS));
/* Skip linkonce sections - we cannot use these section symbols as they may disappear. */
&& (bsym->section->flags & (SEC_CODE | SEC_LINK_ONCE)) == SEC_CODE
/* Not all linkonce sections are flagged... */
- && strncmp (S_GET_NAME (sym), ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) != 0)
+ && !startswith (S_GET_NAME (sym), ".gnu.linkonce"))
{
/* Create a version note. */
frag_now_fix ();
bfd_section_size (bsym->section),
note);
+ /* Mark the section symbol used in relocation so that it will be
+ included in the symbol table. */
+ symbol_mark_used_in_reloc (sym);
+
total_size += note_size;
/* FIXME: Maybe add a note recording the assembler command line and version ? */
}
if (symbol_rootP)
{
symbolS *symp;
- bfd_boolean skip_next_symbol = FALSE;
+ bool skip_next_symbol = false;
for (symp = symbol_rootP; symp; symp = symbol_next (symp))
{
/* Don't do anything besides moving the value of the
symbol from the GAS value-field to the BFD value-field. */
symbol_get_bfdsym (symp)->value = S_GET_VALUE (symp);
- skip_next_symbol = FALSE;
+ skip_next_symbol = false;
continue;
}
symbol warned about. Don't let anything object-format or
target-specific muck with it; it's ready for output. */
if (symbol_get_bfdsym (symp)->flags & BSF_WARNING)
- skip_next_symbol = TRUE;
+ skip_next_symbol = true;
}
}
if (flag_warn_displacement)
{
char buf[50];
- sprint_value (buf, (addressT) lie->addnum);
+
+ bfd_sprintf_vma (stdoutput, buf,
+ (addressT) lie->addnum);
as_warn_where (fragP->fr_file, fragP->fr_line,
_(".word %s-%s+%s didn't fit"),
S_GET_NAME (lie->add),