/* Object file "section" support for the BFD library.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
Free Software Foundation, Inc.
Written by Cygnus Support.
. {* Mark flag used by some linker backends for garbage collection. *}
. unsigned int gc_mark : 1;
.
+. {* Section compression status. *}
+. unsigned int compress_status : 2;
+.#define COMPRESS_SECTION_NONE 0
+.#define COMPRESS_SECTION_DONE 1
+.#define DECOMPRESS_SECTION_SIZED 2
+.
. {* The following flags are used by the ELF linker. *}
.
. {* Mark sections which have been allocated to segments. *}
. {* Bits used by various backends. The generic code doesn't touch
. these fields. *}
.
-. {* Nonzero if this section has TLS related relocations. *}
-. unsigned int has_tls_reloc:1;
-.
-. {* Nonzero if this section has a call to __tls_get_addr. *}
-. unsigned int has_tls_get_addr_call:1;
-.
-. {* Nonzero if this section has a gp reloc. *}
-. unsigned int has_gp_reloc:1;
-.
-. {* Nonzero if this section needs the relax finalize pass. *}
-. unsigned int need_finalize_relax:1;
-.
-. {* Whether relocations have been processed. *}
-. unsigned int reloc_done : 1;
+. unsigned int sec_flg0:1;
+. unsigned int sec_flg1:1;
+. unsigned int sec_flg2:1;
+. unsigned int sec_flg3:1;
+. unsigned int sec_flg4:1;
+. unsigned int sec_flg5:1;
.
. {* End of internal packed boolean fields. *}
.
. section size calculated on a previous linker relaxation pass. *}
. bfd_size_type rawsize;
.
+. {* The compressed size of the section in octets. *}
+. bfd_size_type compressed_size;
+.
+. {* Relaxation table. *}
+. struct relax_table *relax;
+.
+. {* Count of used relaxation table entries. *}
+. int relax_count;
+.
+.
. {* If this section is going to be output, then this value is the
. offset in *bytes* into the output section of the first byte in the
. input section (byte ==> smallest addressable unit on the
. } map_head, map_tail;
.} asection;
.
+.{* Relax table contains information about instructions which can
+. be removed by relaxation -- replacing a long address with a
+. short address. *}
+.struct relax_table {
+. {* Address where bytes may be deleted. *}
+. bfd_vma addr;
+.
+. {* Number of bytes to be deleted. *}
+. int size;
+.};
+.
.{* These sections are global, and are managed by BFD. The application
. and target back end are not permitted to change the values in
. these sections. New code should use the section_ptr macros rather
. {* name, id, index, next, prev, flags, user_set_vma, *} \
. { NAME, IDX, 0, NULL, NULL, FLAGS, 0, \
. \
-. {* linker_mark, linker_has_input, gc_mark, *} \
-. 0, 0, 1, \
+. {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \
+. 0, 0, 1, 0, \
. \
-. {* segment_mark, sec_info_type, use_rela_p, has_tls_reloc, *} \
-. 0, 0, 0, 0, \
+. {* segment_mark, sec_info_type, use_rela_p, *} \
+. 0, 0, 0, \
. \
-. {* has_tls_get_addr_call, has_gp_reloc, need_finalize_relax, *} \
-. 0, 0, 0, \
+. {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \
+. 0, 0, 0, 0, 0, 0, \
. \
-. {* reloc_done, vma, lma, size, rawsize *} \
-. 0, 0, 0, 0, 0, \
+. {* vma, lma, size, rawsize, compressed_size, relax, relax_count, *} \
+. 0, 0, 0, 0, 0, 0, 0, \
. \
. {* output_offset, output_section, alignment_power, *} \
. 0, (struct bfd_section *) &SEC, 0, \
char *sname;
len = strlen (templat);
- sname = bfd_malloc (len + 8);
+ sname = (char *) bfd_malloc (len + 8);
if (sname == NULL)
return NULL;
memcpy (sname, templat, len);
return TRUE;
}
+/*
+FUNCTION
+ bfd_rename_section
+
+SYNOPSIS
+ void bfd_rename_section
+ (bfd *abfd, asection *sec, const char *newname);
+
+DESCRIPTION
+ Rename section @var{sec} in @var{abfd} to @var{newname}.
+*/
+
+void
+bfd_rename_section (bfd *abfd, sec_ptr sec, const char *newname)
+{
+ struct section_hash_entry *sh;
+
+ sh = (struct section_hash_entry *)
+ ((char *) sec - offsetof (struct section_hash_entry, section));
+ sh->section.name = newname;
+ bfd_hash_rename (&abfd->section_htab, newname, &sh->root);
+}
+
/*
FUNCTION
bfd_map_over_sections
if ((section->flags & SEC_IN_MEMORY) != 0)
{
+ if (section->contents == NULL)
+ {
+ /* This can happen because of errors earlier on in the linking process.
+ We do not want to seg-fault here, so clear the flag and return an
+ error code. */
+ section->flags &= ~ SEC_IN_MEMORY;
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
memcpy (location, section->contents + offset, (size_t) count);
return TRUE;
}
bfd_boolean
bfd_malloc_and_get_section (bfd *abfd, sec_ptr sec, bfd_byte **buf)
{
- bfd_size_type sz = sec->rawsize ? sec->rawsize : sec->size;
- bfd_byte *p = NULL;
-
- *buf = p;
- if (sz == 0)
- return TRUE;
-
- p = bfd_malloc (sec->rawsize > sec->size ? sec->rawsize : sec->size);
- if (p == NULL)
- return FALSE;
- *buf = p;
-
- return bfd_get_section_contents (abfd, sec, p, 0, sz);
+ *buf = NULL;
+ return bfd_get_full_section_contents (abfd, sec, buf);
}
/*
FUNCTION