/* write.c - emit .o file
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
static fixS *
fix_new_internal (fragS *frag, /* Which frag? */
- int where, /* Where in that frag? */
- int size, /* 1, 2, or 4 usually. */
+ unsigned long where, /* Where in that frag? */
+ unsigned long size, /* 1, 2, or 4 usually. */
symbolS *add_symbol, /* X_add_symbol. */
symbolS *sub_symbol, /* X_op_symbol. */
offsetT offset, /* X_add_number. */
/* We've made fx_size a narrow field; check that it's wide enough. */
if (fixP->fx_size != size)
{
- as_bad (_("field fx_size too small to hold %d"), size);
+ as_bad (_("field fx_size too small to hold %lu"), size);
abort ();
}
fixP->fx_addsy = add_symbol;
fixP->fx_dot_frag = dot_frag;
fixP->fx_pcrel = pcrel;
fixP->fx_r_type = r_type;
- fixP->fx_im_disp = 0;
fixP->fx_pcrel_adjust = 0;
- fixP->fx_bit_fixP = 0;
fixP->fx_addnumber = 0;
fixP->fx_tcbit = 0;
fixP->fx_tcbit2 = 0;
/* Create a fixup relative to a symbol (plus a constant). */
fixS *
-fix_new (fragS *frag, /* Which frag? */
- int where, /* Where in that frag? */
- int size, /* 1, 2, or 4 usually. */
- symbolS *add_symbol, /* X_add_symbol. */
+fix_new (fragS *frag, /* Which frag? */
+ unsigned long where, /* Where in that frag? */
+ unsigned long size, /* 1, 2, or 4 usually. */
+ symbolS *add_symbol, /* X_add_symbol. */
offsetT offset, /* X_add_number. */
int pcrel, /* TRUE if PC-relative relocation. */
RELOC_ENUM r_type /* Relocation type. */)
fixS *
fix_new_exp (fragS *frag, /* Which frag? */
- int where, /* Where in that frag? */
- int size, /* 1, 2, or 4 usually. */
+ unsigned long where, /* Where in that frag? */
+ unsigned long size, /* 1, 2, or 4 usually. */
expressionS *exp, /* Expression. */
int pcrel, /* TRUE if PC-relative relocation. */
RELOC_ENUM r_type /* Relocation type. */)
as for fix_new, except that WHERE is implicitly 0. */
fixS *
-fix_at_start (fragS *frag, int size, symbolS *add_symbol,
+fix_at_start (fragS *frag, unsigned long size, symbolS *add_symbol,
offsetT offset, int pcrel, RELOC_ENUM r_type)
{
return fix_new_internal (frag, 0, size, add_symbol,
if (seg == absolute_section)
return;
- if (align > bfd_get_section_alignment (stdoutput, seg))
- bfd_set_section_alignment (stdoutput, seg, align);
+ if (align > bfd_section_alignment (seg))
+ bfd_set_section_alignment (seg, align);
}
int
if (seg == absolute_section)
return 0;
- return bfd_get_section_alignment (stdoutput, seg);
+ return bfd_section_alignment (seg);
}
/* Reset the section indices after removing the gas created sections. */
#ifdef HANDLE_ALIGN
HANDLE_ALIGN (fragP);
#endif
-skip_align:
+ skip_align:
know (fragP->fr_next != NULL);
fragP->fr_offset = (fragP->fr_next->fr_address
- fragP->fr_address
md_convert_frag (stdoutput, sec, fragP);
gas_assert (fragP->fr_next == NULL
- || ((offsetT) (fragP->fr_next->fr_address - fragP->fr_address)
- == fragP->fr_fix));
+ || (fragP->fr_next->fr_address - fragP->fr_address
+ == fragP->fr_fix));
/* After md_convert_frag, we make the frag into a ".space 0".
md_convert_frag() should set up any fixSs and constants
}
static void
-size_seg (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
+size_seg (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *xxx ATTRIBUTE_UNUSED)
{
flagword flags;
fragS *fragp;
else
size = 0;
- flags = bfd_get_section_flags (abfd, sec);
- if (size == 0 && bfd_get_section_size (sec) != 0 &&
+ flags = bfd_section_flags (sec);
+ if (size == 0 && bfd_section_size (sec) != 0 &&
(flags & SEC_HAS_CONTENTS) != 0)
return;
flags |= SEC_HAS_CONTENTS;
flags &= ~SEC_RELOC;
- x = bfd_set_section_flags (abfd, sec, flags);
+ x = bfd_set_section_flags (sec, flags);
gas_assert (x);
/* If permitted, allow the backend to pad out the section
newsize = size;
else
newsize = md_section_align (sec, size);
- x = bfd_set_section_size (abfd, sec, newsize);
+ x = bfd_set_section_size (sec, newsize);
gas_assert (x);
/* If the size had to be rounded up, add some padding in the last
symbol_mark_used_in_reloc (fixP->fx_subsy);
}
- if (!fixP->fx_bit_fixP && !fixP->fx_no_overflow && fixP->fx_size != 0)
+ if (!fixP->fx_no_overflow && fixP->fx_size != 0)
{
if (fixP->fx_size < sizeof (valueT))
{
(long) add_number,
(long) (fragP->fr_address + fixP->fx_where));
#endif
- } /* Not a bit fix. */
+ }
#ifdef TC_VALIDATE_FIX
skip: ATTRIBUTE_UNUSED_LABEL
}
static void
-write_relocs (bfd *abfd, asection *sec, void *xxx ATTRIBUTE_UNUSED)
+write_relocs (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
+ void *xxx ATTRIBUTE_UNUSED)
{
segment_info_type *seginfo = seg_info (sec);
unsigned int n;
/* Extract relocs for this section from reloc_list. */
rp = &reloc_list;
+
my_reloc_list = NULL;
while ((r = *rp) != NULL)
{
for (fixp = seginfo->fix_root; fixp != (fixS *) NULL; fixp = fixp->fx_next)
{
int fx_size, slack;
- offsetT loc;
+ valueT loc;
arelent **reloc;
#ifndef RELOC_EXPANSION_POSSIBLE
arelent *rel;
if (n)
{
- flagword flags = bfd_get_section_flags (abfd, sec);
+ flagword flags = bfd_section_flags (sec);
flags |= SEC_RELOC;
- bfd_set_section_flags (abfd, sec, flags);
+ bfd_set_section_flags (sec, flags);
bfd_set_reloc (stdoutput, sec, relocs, n);
}
char *header;
struct z_stream_s *strm;
int x;
- flagword flags = bfd_get_section_flags (abfd, sec);
+ flagword flags = bfd_section_flags (sec);
unsigned int header_size, compression_header_size;
if (seginfo == NULL
|| (flags & (SEC_ALLOC | SEC_HAS_CONTENTS)) == SEC_ALLOC)
return;
- section_name = bfd_get_section_name (stdoutput, sec);
+ section_name = bfd_section_name (sec);
if (strncmp (section_name, ".debug_", 7) != 0)
return;
/* Update the section size and its name. */
bfd_update_compression_header (abfd, (bfd_byte *) header, sec);
- x = bfd_set_section_size (abfd, sec, compressed_size);
+ x = bfd_set_section_size (sec, compressed_size);
gas_assert (x);
if (!compression_header_size)
{
compressed_name = concat (".z", section_name + 1, (char *) NULL);
- bfd_section_name (stdoutput, sec) = compressed_name;
+ bfd_rename_section (sec, compressed_name);
}
}
/* Write out the frags. */
if (seginfo == NULL
- || !(bfd_get_section_flags (abfd, sec) & SEC_HAS_CONTENTS))
+ || !(bfd_section_flags (sec) & SEC_HAS_CONTENTS))
return;
for (f = seginfo->frchainP->frch_root;
do_not_pad_sections_to_alignment = 1;
alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP);
- if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE)
+ if ((bfd_section_flags (now_seg) & SEC_MERGE)
&& now_seg->entsize)
{
unsigned int entsize = now_seg->entsize;
s = subseg_new (name, 0);
elf_section_type (s)
= get_elf_backend_data (stdoutput)->obj_attrs_section_type;
- bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
+ bfd_set_section_flags (s, SEC_READONLY | SEC_DATA);
frag_now_fix ();
p = frag_more (size);
bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size);
size_seg (stdoutput, s, NULL);
}
-#include "struc-symbol.h"
-
/* Create a relocation against an entry in a GNU Build attribute section. */
static void
create_note_reloc (segT sec,
symbolS * sym,
- bfd_size_type offset,
+ bfd_size_type note_offset,
+ bfd_size_type desc2_offset,
int reloc_type,
bfd_vma addend,
char * note)
reloc = XNEW (struct reloc_list);
/* We create a .b type reloc as resolve_reloc_expr_symbols() has already been called. */
- reloc->u.b.sec = sec;
- reloc->u.b.s = sym->bsym;
+ reloc->u.b.sec = sec;
+ reloc->u.b.s = symbol_get_bfdsym (sym);
reloc->u.b.r.sym_ptr_ptr = & reloc->u.b.s;
- reloc->u.b.r.address = offset;
+ reloc->u.b.r.address = note_offset + desc2_offset;
reloc->u.b.r.addend = addend;
reloc->u.b.r.howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
if (target_big_endian)
{
if (bfd_arch_bits_per_address (stdoutput) <= 32)
- note[offset + 3] = addend;
+ note[desc2_offset + 3] = addend;
else
- note[offset + 7] = addend;
+ note[desc2_offset + 7] = addend;
}
else
- note[offset] = addend;
+ note[desc2_offset] = addend;
}
}
offsetT desc2_offset;
int desc_reloc;
symbolS * sym;
+ asymbol * bsym;
if (! flag_generate_build_notes
|| bfd_get_section_by_name (stdoutput,
/* Create a GNU Build Attribute section. */
sec = subseg_new (GNU_BUILD_ATTRS_SECTION_NAME, FALSE);
elf_section_type (sec) = SHT_NOTE;
- bfd_set_section_flags (stdoutput, sec,
- SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA);
- bfd_set_section_alignment (stdoutput, sec, 2);
+ bfd_set_section_flags (sec, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_DATA
+ | SEC_OCTETS));
+ bfd_set_section_alignment (sec, 2);
/* Work out the size of the notes that we will create,
and the relocation we should use. */
total_size = 0;
note = NULL;
- for (sym = symbol_rootP; sym != NULL; sym = sym->sy_next)
- if (sym->bsym != NULL
- && sym->bsym->flags & BSF_SECTION_SYM
- && sym->bsym->section != NULL
+ for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
+ if ((bsym = symbol_get_bfdsym (sym)) != NULL
+ && bsym->flags & BSF_SECTION_SYM
+ && bsym->section != NULL
/* Skip linkonce sections - we cannot use these section symbols as they may disappear. */
- && (sym->bsym->section->flags & (SEC_CODE | SEC_LINK_ONCE)) == SEC_CODE
+ && (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)
{
memcpy (note + 12, "GA$\ 13a1", 8);
/* Create a relocation to install the start address of the note... */
- create_note_reloc (sec, sym, total_size + 20, desc_reloc, 0, note);
+ create_note_reloc (sec, sym, total_size, 20, desc_reloc, 0, note);
/* ...and another one to install the end address. */
- create_note_reloc (sec, sym, total_size + desc2_offset, desc_reloc,
- bfd_get_section_size (sym->bsym->section),
+ create_note_reloc (sec, sym, total_size, desc2_offset, desc_reloc,
+ bfd_section_size (bsym->section),
note);
total_size += note_size;
if (IS_ELF)
maybe_generate_build_notes ();
#endif
-
+
PROGRESS (1);
#ifdef tc_frob_file_before_adjust
#endif
/* Stop if there is an error. */
- if (had_errors ())
+ if (!flag_always_generate_output && had_errors ())
return;
/* Now that all the sizes are known, and contents correct, we can
}
#ifdef TC_GENERIC_RELAX_TABLE
+#ifndef md_generic_table_relax_frag
+#define md_generic_table_relax_frag relax_frag
+#endif
+
/* Relax a fragment by scanning TC_GENERIC_RELAX_TABLE. */
long
const relax_typeS *table;
target = fragP->fr_offset;
- address = fragP->fr_address;
+ address = fragP->fr_address + fragP->fr_fix;
table = TC_GENERIC_RELAX_TABLE;
this_state = fragP->fr_subtype;
start_type = this_type = table + this_state;
negative. Don't allow this in case the negative reach is
large enough to require a larger branch instruction. */
else if (target < address)
- target = fragP->fr_next->fr_address + stretch;
+ return 0;
}
}
- aim = target - address - fragP->fr_fix;
+ aim = target - address;
#ifdef TC_PCREL_ADJUST
- /* Currently only the ns32k family needs this. */
+ /* Currently only the ns32k and arc needs this. */
aim += TC_PCREL_ADJUST (fragP);
#endif
#ifdef TC_GENERIC_RELAX_TABLE
/* The default way to relax a frag is to look through
TC_GENERIC_RELAX_TABLE. */
- growth = relax_frag (segment, fragP, stretch);
+ growth = md_generic_table_relax_frag (segment, fragP,
+ stretch);
#endif /* TC_GENERIC_RELAX_TABLE */
#endif
break;
fprintf (stderr, " pcrel");
if (fixp->fx_pcrel_adjust)
fprintf (stderr, " pcrel_adjust=%d", fixp->fx_pcrel_adjust);
- if (fixp->fx_im_disp)
- {
-#ifdef TC_NS32K
- fprintf (stderr, " im_disp=%d", fixp->fx_im_disp);
-#else
- fprintf (stderr, " im_disp");
-#endif
- }
if (fixp->fx_tcbit)
fprintf (stderr, " tcbit");
if (fixp->fx_done)