1,6 → 1,5 |
/* SEC_MERGE support. |
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 |
Free Software Foundation, Inc. |
Copyright (C) 2001-2015 Free Software Foundation, Inc. |
Written by Jakub Jelinek <jakub@redhat.com>. |
|
This file is part of BFD, the Binary File Descriptor library. |
26,6 → 25,7 |
|
#include "sysdep.h" |
#include "bfd.h" |
#include "elf-bfd.h" |
#include "libbfd.h" |
#include "hashtab.h" |
#include "libiberty.h" |
284,7 → 284,8 |
} |
|
static bfd_boolean |
sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry) |
sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry, |
unsigned char *contents, file_ptr offset) |
{ |
struct sec_merge_sec_info *secinfo = entry->secinfo; |
asection *sec = secinfo->sec; |
307,7 → 308,12 |
len = -off & (entry->alignment - 1); |
if (len != 0) |
{ |
if (bfd_bwrite (pad, len, abfd) != len) |
if (contents) |
{ |
memcpy (contents + offset, pad, len); |
offset += len; |
} |
else if (bfd_bwrite (pad, len, abfd) != len) |
goto err; |
off += len; |
} |
315,7 → 321,12 |
str = entry->root.string; |
len = entry->len; |
|
if (bfd_bwrite (str, len, abfd) != len) |
if (contents) |
{ |
memcpy (contents + offset, str, len); |
offset += len; |
} |
else if (bfd_bwrite (str, len, abfd) != len) |
goto err; |
|
off += len; |
323,9 → 334,13 |
|
/* Trailing alignment needed? */ |
off = sec->size - off; |
if (off != 0 |
&& bfd_bwrite (pad, off, abfd) != off) |
if (off != 0) |
{ |
if (contents) |
memcpy (contents + offset, pad, off); |
else if (bfd_bwrite (pad, off, abfd) != off) |
goto err; |
} |
|
if (pad != NULL) |
free (pad); |
786,6 → 801,8 |
{ |
struct sec_merge_sec_info *secinfo; |
file_ptr pos; |
unsigned char *contents; |
Elf_Internal_Shdr *hdr; |
|
secinfo = (struct sec_merge_sec_info *) psecinfo; |
|
796,11 → 813,26 |
return TRUE; |
|
/* FIXME: octets_per_byte. */ |
hdr = &elf_section_data (sec->output_section)->this_hdr; |
if (hdr->sh_offset == (file_ptr) -1) |
{ |
/* We must compress this section. Write output to the |
buffer. */ |
contents = hdr->contents; |
if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0 |
|| contents == NULL) |
abort (); |
} |
else |
{ |
contents = NULL; |
pos = sec->output_section->filepos + sec->output_offset; |
if (bfd_seek (output_bfd, pos, SEEK_SET) != 0) |
return FALSE; |
} |
|
if (! sec_merge_emit (output_bfd, secinfo->first_str)) |
if (! sec_merge_emit (output_bfd, secinfo->first_str, contents, |
sec->output_offset)) |
return FALSE; |
|
return TRUE; |