diff options
Diffstat (limited to 'bfd/section.c')
-rw-r--r-- | bfd/section.c | 256 |
1 files changed, 179 insertions, 77 deletions
diff --git a/bfd/section.c b/bfd/section.c index fce8e1eab3d..b368c2aa842 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -1,6 +1,6 @@ /* Object file "section" support for the BFD library. Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003 + 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Written by Cygnus Support. @@ -149,23 +149,6 @@ SUBSECTION CODE_FRAGMENT . -.{* This structure is used for a comdat section, as in PE. A comdat -. section is associated with a particular symbol. When the linker -. sees a comdat section, it keeps only one of the sections with a -. given name and associated with a given symbol. *} -. -.struct bfd_comdat_info -.{ -. {* The name of the symbol associated with a comdat section. *} -. const char *name; -. -. {* The local symbol table index of the symbol associated with a -. comdat section. This is only meaningful to the object file format -. specific code; it is not an index into the list returned by -. bfd_canonicalize_symtab. *} -. long symbol; -.}; -. .typedef struct bfd_section .{ . {* The name of the section; the name isn't a copy, the pointer is @@ -364,9 +347,6 @@ CODE_FRAGMENT . {* See the vma field. *} . unsigned int user_set_vma : 1; . -. {* Whether relocations have been processed. *} -. unsigned int reloc_done : 1; -. . {* A mark flag used by some of the linker backends. *} . unsigned int linker_mark : 1; . @@ -394,21 +374,18 @@ CODE_FRAGMENT . unsigned int use_rela_p:1; . . {* Bits used by various backends. *} -. unsigned int has_tls_reloc:1; . -. {* Nonzero if this section needs the relax finalize pass. *} -. unsigned int need_finalize_relax:1; +. {* Nonzero if this section has TLS related relocations. *} +. unsigned int has_tls_reloc:1; . . {* Nonzero if this section has a gp reloc. *} . unsigned int has_gp_reloc:1; . -. {* Unused bits. *} -. unsigned int flag13:1; -. unsigned int flag14:1; -. unsigned int flag15:1; -. unsigned int flag16:4; -. unsigned int flag20:4; -. unsigned int flag24:8; +. {* 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; . . {* End of internal packed boolean fields. *} . @@ -427,13 +404,18 @@ CODE_FRAGMENT . . {* The size of the section in octets, as it will be output. . Contains a value even if the section has no contents (e.g., the -. size of <<.bss>>). This will be filled in after relocation. *} -. bfd_size_type _cooked_size; -. -. {* The original size on disk of the section, in octets. Normally this -. value is the same as the size, but if some relaxing has -. been done, then this value will be bigger. *} -. bfd_size_type _raw_size; +. size of <<.bss>>). *} +. bfd_size_type size; +. +. {* For input sections, the original size on disk of the section, in +. octets. This field is used by the linker relaxation code. It is +. currently only set for sections where the linker relaxation scheme +. doesn't cache altered section and reloc contents (stabs, eh_frame, +. SEC_MERGE, some coff relaxing targets), and thus the original size +. needs to be kept to read the section multiple times. +. For output sections, rawsize holds the section size calculated on +. a previous linker relaxation pass. *} +. bfd_size_type rawsize; . . {* 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 @@ -490,9 +472,6 @@ CODE_FRAGMENT . {* Entity size for merging purposes. *} . unsigned int entsize; . -. {* Optional information about a COMDAT entry; NULL if not COMDAT. *} -. struct bfd_comdat_info *comdat; -. . {* Points to the kept section if this section is a link-once section, . and is discarded. *} . struct bfd_section *kept_section; @@ -557,11 +536,6 @@ CODE_FRAGMENT .extern const struct bfd_symbol * const bfd_com_symbol; .extern const struct bfd_symbol * const bfd_und_symbol; .extern const struct bfd_symbol * const bfd_ind_symbol; -.#define bfd_get_section_size_before_reloc(section) \ -. ((section)->_raw_size) -.#define bfd_get_section_size_after_reloc(section) \ -. ((section)->reloc_done ? (section)->_cooked_size \ -. : (abort (), (bfd_size_type) 1)) . .{* Macros to handle insertion and deletion of a bfd's sections. These . only handle the list pointers, ie. do not adjust section_count, @@ -616,25 +590,22 @@ static const asymbol global_syms[] = #define STD_SECTION(SEC, FLAGS, SYM, NAME, IDX) \ const asymbol * const SYM = (asymbol *) &global_syms[IDX]; \ asection SEC = \ - /* name, id, index, next, flags, user_set_vma, reloc_done, */ \ - { NAME, IDX, 0, NULL, FLAGS, 0, 0, \ + /* name, id, index, next, flags, user_set_vma, */ \ + { NAME, IDX, 0, NULL, FLAGS, 0, \ \ /* linker_mark, linker_has_input, gc_mark, segment_mark, */ \ 0, 0, 1, 0, \ \ - /* sec_info_type, use_rela_p, has_tls_reloc, */ \ - 0, 0, 0, \ + /* sec_info_type, use_rela_p, has_tls_reloc, has_gp_reloc, */ \ + 0, 0, 0, 0, \ \ - /* need_finalize_relax, has_gp_reloc, */ \ + /* need_finalize_relax, reloc_done, */ \ 0, 0, \ \ - /* flag13, flag14, flag15, flag16, flag20, flag24, */ \ - 0, 0, 0, 0, 0, 0, \ - \ - /* vma, lma, _cooked_size, _raw_size, */ \ - 0, 0, 0, 0, \ + /* vma, lma, size, rawsize */ \ + 0, 0, 0, 0, \ \ - /* output_offset, output_section, alignment_power, */ \ + /* output_offset, output_section, alignment_power, */ \ 0, (struct bfd_section *) &SEC, 0, \ \ /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ @@ -643,8 +614,8 @@ static const asymbol global_syms[] = /* line_filepos, userdata, contents, lineno, lineno_count, */ \ 0, NULL, NULL, NULL, 0, \ \ - /* entsize, comdat, kept_section, moving_line_filepos, */ \ - 0, NULL, NULL, 0, \ + /* entsize, kept_section, moving_line_filepos, */ \ + 0, NULL, 0, \ \ /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ @@ -801,6 +772,57 @@ bfd_get_section_by_name (bfd *abfd, const char *name) /* FUNCTION + bfd_get_section_by_name_if + +SYNOPSIS + asection *bfd_get_section_by_name_if + (bfd *abfd, + const char *name, + bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj), + void *obj); + +DESCRIPTION + Call the provided function @var{func} for each section + attached to the BFD @var{abfd} whose name matches @var{name}, + passing @var{obj} as an argument. The function will be called + as if by + +| func (abfd, the_section, obj); + + It returns the first section for which @var{func} returns true, + otherwise <<NULL>>. + +*/ + +asection * +bfd_get_section_by_name_if (bfd *abfd, const char *name, + bfd_boolean (*operation) (bfd *, + asection *, + void *), + void *user_storage) +{ + struct section_hash_entry *sh; + unsigned long hash; + + sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE); + if (sh == NULL) + return NULL; + + hash = sh->root.hash; + do + { + if ((*operation) (abfd, &sh->section, user_storage)) + return &sh->section; + sh = (struct section_hash_entry *) sh->root.next; + } + while (sh != NULL && sh->root.hash == hash + && strcmp (sh->root.string, name) == 0); + + return NULL; +} + +/* +FUNCTION bfd_get_unique_section_name SYNOPSIS @@ -945,13 +967,19 @@ bfd_make_section_anyway (bfd *abfd, const char *name) newsect = &sh->section; if (newsect->name != NULL) { - /* We are making a section of the same name. It can't go in - section_htab without generating a unique section name and - that would be pointless; We don't need to traverse the - hash table. */ - newsect = bfd_zalloc (abfd, sizeof (asection)); - if (newsect == NULL) + /* We are making a section of the same name. Put it in the + section hash table. Even though we can't find it directly by a + hash lookup, we'll be able to find the section by traversing + sh->root.next quicker than looking at all the bfd sections. */ + struct section_hash_entry *new_sh; + new_sh = (struct section_hash_entry *) + bfd_section_hash_newfunc (NULL, &abfd->section_htab, name); + if (new_sh == NULL) return NULL; + + new_sh->root = sh->root; + sh->root.next = &new_sh->root; + newsect = &new_sh->section; } newsect->name = name; @@ -1090,6 +1118,41 @@ bfd_map_over_sections (bfd *abfd, /* FUNCTION + bfd_sections_find_if + +SYNOPSIS + asection *bfd_sections_find_if + (bfd *abfd, + bfd_boolean (*operation) (bfd *abfd, asection *sect, void *obj), + void *obj); + +DESCRIPTION + Call the provided function @var{operation} for each section + attached to the BFD @var{abfd}, passing @var{obj} as an + argument. The function will be called as if by + +| operation (abfd, the_section, obj); + + It returns the first section for which @var{operation} returns true. + +*/ + +asection * +bfd_sections_find_if (bfd *abfd, + bfd_boolean (*operation) (bfd *, asection *, void *), + void *user_storage) +{ + asection *sect; + + for (sect = abfd->sections; sect != NULL; sect = sect->next) + if ((*operation) (abfd, sect, user_storage)) + break; + + return sect; +} + +/* +FUNCTION bfd_set_section_size SYNOPSIS @@ -1118,9 +1181,7 @@ bfd_set_section_size (bfd *abfd, sec_ptr ptr, bfd_size_type val) return FALSE; } - ptr->_cooked_size = val; - ptr->_raw_size = val; - + ptr->size = val; return TRUE; } @@ -1151,11 +1212,6 @@ DESCRIPTION */ -#define bfd_get_section_size_now(abfd, sec) \ - (sec->reloc_done \ - ? bfd_get_section_size_after_reloc (sec) \ - : bfd_get_section_size_before_reloc (sec)) - bfd_boolean bfd_set_section_contents (bfd *abfd, sec_ptr section, @@ -1171,7 +1227,7 @@ bfd_set_section_contents (bfd *abfd, return FALSE; } - sz = bfd_get_section_size_now (abfd, section); + sz = section->size; if ((bfd_size_type) offset > sz || count > sz || offset + count > sz @@ -1251,9 +1307,7 @@ bfd_get_section_contents (bfd *abfd, return TRUE; } - /* Even if reloc_done is TRUE, this function reads unrelocated - contents, so we want the raw size. */ - sz = section->_raw_size; + sz = section->rawsize ? section->rawsize : section->size; if ((bfd_size_type) offset > sz || count > sz || offset + count > sz @@ -1285,6 +1339,36 @@ bfd_get_section_contents (bfd *abfd, /* FUNCTION + bfd_malloc_and_get_section + +SYNOPSIS + bfd_boolean bfd_malloc_and_get_section + (bfd *abfd, asection *section, bfd_byte **buf); + +DESCRIPTION + Read all data from @var{section} in BFD @var{abfd} + into a buffer, *@var{buf}, malloc'd by this function. +*/ + +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); +} +/* +FUNCTION bfd_copy_private_section_data SYNOPSIS @@ -1351,6 +1435,24 @@ _bfd_strip_section_from_output (struct bfd_link_info *info, asection *s) /* FUNCTION + bfd_generic_is_group_section + +SYNOPSIS + bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec); + +DESCRIPTION + Returns TRUE if @var{sec} is a member of a group. +*/ + +bfd_boolean +bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, + const asection *sec ATTRIBUTE_UNUSED) +{ + return FALSE; +} + +/* +FUNCTION bfd_generic_discard_group SYNOPSIS |