X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fsection.c;h=fb19d8cc3afbdfc3ceb8e9a4c8c6a32d35567a86;hb=a5b5d5ae56990bfe06a77d4de82ed359669a2db2;hp=d92dc2d4d7a7d8b7f5588041e54792ae23d16bcd;hpb=a50b1753d42fa4c760f96d72890684d3a3a221d0;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/section.c b/bfd/section.c index d92dc2d4d7..fb19d8cc3a 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -1,6 +1,7 @@ /* 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, 2011, + 2012, 2013 Free Software Foundation, Inc. Written by Cygnus Support. @@ -327,6 +328,11 @@ CODE_FRAGMENT . sections. *} .#define SEC_COFF_SHARED_LIBRARY 0x4000000 . +. {* This input section should be copied to output in reverse order +. as an array of pointers. This is for ELF linker internal use +. only. *} +.#define SEC_ELF_REVERSE_COPY 0x4000000 +. . {* This section contains data which may be shared with other . executables or shared objects. This is for COFF only. *} .#define SEC_COFF_SHARED 0x8000000 @@ -364,6 +370,12 @@ CODE_FRAGMENT . {* 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. *} @@ -371,11 +383,11 @@ CODE_FRAGMENT . . {* Type of sec_info information. *} . unsigned int sec_info_type:3; -.#define ELF_INFO_TYPE_NONE 0 -.#define ELF_INFO_TYPE_STABS 1 -.#define ELF_INFO_TYPE_MERGE 2 -.#define ELF_INFO_TYPE_EH_FRAME 3 -.#define ELF_INFO_TYPE_JUST_SYMS 4 +.#define SEC_INFO_TYPE_NONE 0 +.#define SEC_INFO_TYPE_STABS 1 +.#define SEC_INFO_TYPE_MERGE 2 +.#define SEC_INFO_TYPE_EH_FRAME 3 +.#define SEC_INFO_TYPE_JUST_SYMS 4 . . {* Nonzero if this section uses RELA relocations, rather than REL. *} . unsigned int use_rela_p:1; @@ -383,20 +395,12 @@ CODE_FRAGMENT . {* 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. *} . @@ -428,6 +432,9 @@ CODE_FRAGMENT . 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; . @@ -525,40 +532,37 @@ CODE_FRAGMENT .} asection; . .{* Relax table contains information about instructions which can -. be removed by relaxation -- replacing a long address with a +. 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 -. than referring directly to the const sections. The const sections -. may eventually vanish. *} +. these sections. *} +.extern asection _bfd_std_section[4]; +. .#define BFD_ABS_SECTION_NAME "*ABS*" .#define BFD_UND_SECTION_NAME "*UND*" .#define BFD_COM_SECTION_NAME "*COM*" .#define BFD_IND_SECTION_NAME "*IND*" . -.{* The absolute section. *} -.extern asection bfd_abs_section; -.#define bfd_abs_section_ptr ((asection *) &bfd_abs_section) -.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) -.{* Pointer to the undefined section. *} -.extern asection bfd_und_section; -.#define bfd_und_section_ptr ((asection *) &bfd_und_section) -.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) .{* Pointer to the common section. *} -.extern asection bfd_com_section; -.#define bfd_com_section_ptr ((asection *) &bfd_com_section) +.#define bfd_com_section_ptr (&_bfd_std_section[0]) +.{* Pointer to the undefined section. *} +.#define bfd_und_section_ptr (&_bfd_std_section[1]) +.{* Pointer to the absolute section. *} +.#define bfd_abs_section_ptr (&_bfd_std_section[2]) .{* Pointer to the indirect section. *} -.extern asection bfd_ind_section; -.#define bfd_ind_section_ptr ((asection *) &bfd_ind_section) +.#define bfd_ind_section_ptr (&_bfd_std_section[3]) +. +.#define bfd_is_und_section(sec) ((sec) == bfd_und_section_ptr) +.#define bfd_is_abs_section(sec) ((sec) == bfd_abs_section_ptr) .#define bfd_is_ind_section(sec) ((sec) == bfd_ind_section_ptr) . .#define bfd_is_const_section(SEC) \ @@ -661,20 +665,20 @@ CODE_FRAGMENT . {* 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, relax, relax_count, *} \ -. 0, 0, 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, \ +. {* output_offset, output_section, alignment_power, *} \ +. 0, &SEC, 0, \ . \ . {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \ . NULL, NULL, 0, 0, 0, \ @@ -703,10 +707,10 @@ CODE_FRAGMENT /* the_bfd, name, value, attr, section [, udata] */ #ifdef __STDC__ #define GLOBAL_SYM_INIT(NAME, SECTION) \ - { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION, { 0 }} + { 0, NAME, 0, BSF_SECTION_SYM, SECTION, { 0 }} #else #define GLOBAL_SYM_INIT(NAME, SECTION) \ - { 0, NAME, 0, BSF_SECTION_SYM, (asection *) SECTION } + { 0, NAME, 0, BSF_SECTION_SYM, SECTION } #endif /* These symbols are global, not specific to any BFD. Therefore, anything @@ -714,20 +718,21 @@ CODE_FRAGMENT static const asymbol global_syms[] = { - GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, &bfd_com_section), - GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, &bfd_und_section), - GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, &bfd_abs_section), - GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, &bfd_ind_section) + GLOBAL_SYM_INIT (BFD_COM_SECTION_NAME, bfd_com_section_ptr), + GLOBAL_SYM_INIT (BFD_UND_SECTION_NAME, bfd_und_section_ptr), + GLOBAL_SYM_INIT (BFD_ABS_SECTION_NAME, bfd_abs_section_ptr), + GLOBAL_SYM_INIT (BFD_IND_SECTION_NAME, bfd_ind_section_ptr) }; -#define STD_SECTION(SEC, FLAGS, NAME, IDX) \ - asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], \ - NAME, IDX) +#define STD_SECTION(NAME, IDX, FLAGS) \ + BFD_FAKE_SECTION(_bfd_std_section[IDX], FLAGS, &global_syms[IDX], NAME, IDX) -STD_SECTION (bfd_com_section, SEC_IS_COMMON, BFD_COM_SECTION_NAME, 0); -STD_SECTION (bfd_und_section, 0, BFD_UND_SECTION_NAME, 1); -STD_SECTION (bfd_abs_section, 0, BFD_ABS_SECTION_NAME, 2); -STD_SECTION (bfd_ind_section, 0, BFD_IND_SECTION_NAME, 3); +asection _bfd_std_section[] = { + STD_SECTION (BFD_COM_SECTION_NAME, 0, SEC_IS_COMMON), + STD_SECTION (BFD_UND_SECTION_NAME, 1, 0), + STD_SECTION (BFD_ABS_SECTION_NAME, 2, 0), + STD_SECTION (BFD_IND_SECTION_NAME, 3, 0) +}; #undef STD_SECTION /* Initialize an entry in the section hash table. */ @@ -830,6 +835,7 @@ bfd_section_list_clear (bfd *abfd) abfd->section_count = 0; memset (abfd->section_htab.table, 0, abfd->section_htab.size * sizeof (struct bfd_hash_entry *)); + abfd->section_htab.count = 0; } /* @@ -840,14 +846,8 @@ SYNOPSIS asection *bfd_get_section_by_name (bfd *abfd, const char *name); DESCRIPTION - Run through @var{abfd} and return the one of the - <>s whose name matches @var{name}, otherwise <>. - @xref{Sections}, for more information. - - This should only be used in special cases; the normal way to process - all sections of a given name is to use <> and - <> on the name (or better yet, base it on the section flags - or something else) for each section. + Return the most recently created section attached to @var{abfd} + named @var{name}. Return NULL if no such section exists. */ asection * @@ -862,6 +862,63 @@ bfd_get_section_by_name (bfd *abfd, const char *name) return NULL; } +/* +FUNCTION + bfd_get_next_section_by_name + +SYNOPSIS + asection *bfd_get_next_section_by_name (asection *sec); + +DESCRIPTION + Given @var{sec} is a section returned by @code{bfd_get_section_by_name}, + return the next most recently created section attached to the same + BFD with the same name. Return NULL if no such section exists. +*/ + +asection * +bfd_get_next_section_by_name (asection *sec) +{ + struct section_hash_entry *sh; + const char *name; + unsigned long hash; + + sh = ((struct section_hash_entry *) + ((char *) sec - offsetof (struct section_hash_entry, section))); + + hash = sh->root.hash; + name = sec->name; + for (sh = (struct section_hash_entry *) sh->root.next; + sh != NULL; + sh = (struct section_hash_entry *) sh->root.next) + if (sh->root.hash == hash + && strcmp (sh->root.string, name) == 0) + return &sh->section; + + return NULL; +} + +/* +FUNCTION + bfd_get_linker_section + +SYNOPSIS + asection *bfd_get_linker_section (bfd *abfd, const char *name); + +DESCRIPTION + Return the linker created section attached to @var{abfd} + named @var{name}. Return NULL if no such section exists. +*/ + +asection * +bfd_get_linker_section (bfd *abfd, const char *name) +{ + asection *sec = bfd_get_section_by_name (abfd, name); + + while (sec != NULL && (sec->flags & SEC_LINKER_CREATED) == 0) + sec = bfd_get_next_section_by_name (sec); + return sec; +} + /* FUNCTION bfd_get_section_by_name_if @@ -1212,6 +1269,29 @@ bfd_set_section_flags (bfd *abfd ATTRIBUTE_UNUSED, 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 @@ -1232,7 +1312,7 @@ DESCRIPTION This is the preferred method for iterating over sections; an alternative would be to use a loop: -| section *p; +| asection *p; | for (p = abfd->sections; p != NULL; p = p->next) | func (abfd, p, ...) @@ -1432,7 +1512,10 @@ bfd_get_section_contents (bfd *abfd, return TRUE; } - sz = section->rawsize ? section->rawsize : section->size; + if (abfd->direction != write_direction && section->rawsize != 0) + sz = section->rawsize; + else + sz = section->size; if ((bfd_size_type) offset > sz || count > sz || offset + count > sz @@ -1463,8 +1546,8 @@ bfd_get_section_contents (bfd *abfd, bfd_set_error (bfd_error_invalid_operation); return FALSE; } - - memcpy (location, section->contents + offset, (size_t) count); + + memmove (location, section->contents + offset, (size_t) count); return TRUE; } @@ -1488,20 +1571,8 @@ DESCRIPTION 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_byte *) - 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