* mmo.c (mmo File layout documentation): Add note about low bits
of address. (mmo_write_chunk): When handling data remainder, assert that previous remaining data is flushed. (mmo_write_loc_chunk): Only look for trailing and leading zeros when dealing with an aligned VMA and for aligned lengths. Don't skip the last 32-bit-word of zeros. (mmo_write_loc_chunk): Emit an error if the VMA is not aligned. (mmo_scan) <case LOP_QUOTE>: Move re-alignment of vma before emitting data, not after updating it. <case LOP_LOC>: Call mmo_decide_section with aligned vma.
This commit is contained in:
parent
39d1b2aef3
commit
1218d67db1
2 changed files with 56 additions and 14 deletions
|
@ -1,3 +1,17 @@
|
|||
2014-05-01 Hans-Peter Nilsson <hp@bitrange.com>
|
||||
|
||||
* mmo.c (mmo File layout documentation): Add note about low bits
|
||||
of address.
|
||||
(mmo_write_chunk): When handling data remainder, assert that
|
||||
previous remaining data is flushed.
|
||||
(mmo_write_loc_chunk): Only look for trailing and leading zeros
|
||||
when dealing with an aligned VMA and for aligned lengths. Don't skip
|
||||
the last 32-bit-word of zeros.
|
||||
(mmo_write_loc_chunk): Emit an error if the VMA is not aligned.
|
||||
(mmo_scan) <case LOP_QUOTE>: Move re-alignment of vma before
|
||||
emitting data, not after updating it.
|
||||
<case LOP_LOC>: Call mmo_decide_section with aligned vma.
|
||||
|
||||
2014-04-30 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* compress.c (bfd_is_section_compressed): When checking the
|
||||
|
|
56
bfd/mmo.c
56
bfd/mmo.c
|
@ -88,7 +88,11 @@ SUBSECTION
|
|||
directive, setting the location for the next data to the next
|
||||
32-bit word (for @math{Z = 1}) or 64-bit word (for @math{Z = 2}),
|
||||
plus @math{Y * 2^56}. Normally @samp{Y} is 0 for the text segment
|
||||
and 2 for the data segment.
|
||||
and 2 for the data segment. Beware that the low bits of non-
|
||||
tetrabyte-aligned values are silently discarded when being
|
||||
automatically incremented and when storing contents (in contrast
|
||||
to e.g. its use as current location when followed by lop_fixo
|
||||
et al before the next possibly-quoted tetrabyte contents).
|
||||
|
||||
@item lop_skip
|
||||
0x9802YYZZ. Increase the current location by @samp{YZ} bytes.
|
||||
|
@ -822,6 +826,9 @@ mmo_write_chunk (bfd *abfd, const bfd_byte *loc, unsigned int len)
|
|||
|
||||
if (len)
|
||||
{
|
||||
/* We must have flushed a previous remainder if we get one from
|
||||
this chunk too. */
|
||||
BFD_ASSERT (mmop->byte_no == 0);
|
||||
memcpy (mmop->buf, loc, len);
|
||||
mmop->byte_no = len;
|
||||
}
|
||||
|
@ -869,25 +876,27 @@ static bfd_boolean
|
|||
mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
|
||||
unsigned int len, bfd_vma *last_vmap)
|
||||
{
|
||||
/* Find an initial and trailing section of zero tetras; we don't need to
|
||||
write out zeros. FIXME: When we do this, we should emit section size
|
||||
and address specifiers, else objcopy can't always perform an identity
|
||||
translation. Only do this if we *don't* have left-over data from a
|
||||
previous write or the vma of this chunk is *not* the next address,
|
||||
because then data isn't tetrabyte-aligned and we're concatenating to
|
||||
that left-over data. */
|
||||
/* Find an initial and trailing section of zero (aligned) tetras; we don't
|
||||
need to write out zeros. FIXME: When we do this, we should emit
|
||||
section size and address specifiers, else objcopy can't always perform
|
||||
an identity translation. Only do this if we *don't* have left-over
|
||||
data from a previous write (and will not add any) or else the vma of
|
||||
this chunk is *not* the next address, because then data isn't
|
||||
tetrabyte-aligned and we're concatenating to that left-over data. */
|
||||
|
||||
if (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap)
|
||||
if ((vma & 3) == 0
|
||||
&& (abfd->tdata.mmo_data->byte_no == 0 || vma != *last_vmap))
|
||||
{
|
||||
while (len >= 4 && bfd_get_32 (abfd, loc) == 0)
|
||||
while (len > 4 && bfd_get_32 (abfd, loc) == 0)
|
||||
{
|
||||
vma += 4;
|
||||
len -= 4;
|
||||
loc += 4;
|
||||
}
|
||||
|
||||
while (len >= 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
|
||||
len -= 4;
|
||||
if ((len & 3) == 0)
|
||||
while (len > 4 && bfd_get_32 (abfd, loc + len - 4) == 0)
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
/* Only write out the location if it's different than the one the caller
|
||||
|
@ -897,6 +906,22 @@ mmo_write_loc_chunk (bfd *abfd, bfd_vma vma, const bfd_byte *loc,
|
|||
/* We might be in the middle of a sequence. */
|
||||
mmo_flush_chunk (abfd);
|
||||
|
||||
/* This should not happen during normal usage, but can presumably
|
||||
happen with an erroneous linker-script, so handle gracefully.
|
||||
Avoid Knuth-specific terms in the message, such as "tetrabyte".
|
||||
Note that this function will get non-4-multiple lengths and
|
||||
unaligned vmas but those come in tuples (mostly pairs) and are
|
||||
continuous (i.e. the if-condition above false) and they are
|
||||
group-wise aligned. */
|
||||
if ((vma & 3) != 0)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
(_("%s: attempt to emit contents at non-multiple-of-4 address 0x%lx\n"),
|
||||
bfd_get_filename (abfd), (unsigned long) vma);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* We always write the location as 64 bits; no use saving bytes
|
||||
here. */
|
||||
mmo_write_tetra_raw (abfd, (LOP << 24) | (LOP_LOC << 16) | 2);
|
||||
|
@ -1583,9 +1608,9 @@ mmo_scan (bfd *abfd)
|
|||
if (bfd_bread (buf, 4, abfd) != 4)
|
||||
goto error_return;
|
||||
|
||||
vma &= ~3;
|
||||
mmo_xore_32 (sec, vma, bfd_get_32 (abfd, buf));
|
||||
vma += 4;
|
||||
vma &= ~3;
|
||||
lineno++;
|
||||
break;
|
||||
|
||||
|
@ -1617,7 +1642,10 @@ mmo_scan (bfd *abfd)
|
|||
goto error_return;
|
||||
}
|
||||
|
||||
sec = mmo_decide_section (abfd, vma);
|
||||
/* When we decide which section the data goes into, we might
|
||||
create the section. If that happens, make sure the VMA at
|
||||
creation time is tetra-aligned. */
|
||||
sec = mmo_decide_section (abfd, vma & ~3);
|
||||
if (sec == NULL)
|
||||
goto error_return;
|
||||
break;
|
||||
|
|
Loading…
Add table
Reference in a new issue