diff options
author | Terry Guo <terry.guo@arm.com> | 2014-09-29 10:12:10 +0800 |
---|---|---|
committer | Terry Guo <terry.guo@arm.com> | 2014-09-29 10:12:10 +0800 |
commit | d98b0e2bf6120f50db57ff68eb9b2e00a9a26154 (patch) | |
tree | df624b46ff896cff7e7cadc23c8ef6dabce146df /gas/write.c | |
parent | 1b7ee89b52d48adf343e6ffa8808ff238b8cfb9d (diff) | |
download | gdb-d98b0e2bf6120f50db57ff68eb9b2e00a9a26154.zip gdb-d98b0e2bf6120f50db57ff68eb9b2e00a9a26154.tar.gz gdb-d98b0e2bf6120f50db57ff68eb9b2e00a9a26154.tar.bz2 |
2014-09-29 Terry Guo <terry.guo@arm.com>
* as.c (create_obj_attrs_section): Move it and call it from ...
* write.c (create_obj_attrs_section): ... here.
(subsegs_finish_section): Refactored.
Diffstat (limited to 'gas/write.c')
-rw-r--r-- | gas/write.c | 124 |
1 files changed, 82 insertions, 42 deletions
diff --git a/gas/write.c b/gas/write.c index d1918e6..0657b56 100644 --- a/gas/write.c +++ b/gas/write.c @@ -1693,64 +1693,99 @@ set_symtab (void) #endif static void -subsegs_finish (void) +subsegs_finish_section (asection *s) { struct frchain *frchainP; - asection *s; + segment_info_type *seginfo = seg_info (s); + if (!seginfo) + return; - for (s = stdoutput->sections; s; s = s->next) + for (frchainP = seginfo->frchainP; + frchainP != NULL; + frchainP = frchainP->frch_next) { - segment_info_type *seginfo = seg_info (s); - if (!seginfo) - continue; + int alignment = 0; - for (frchainP = seginfo->frchainP; - frchainP != NULL; - frchainP = frchainP->frch_next) - { - int alignment = 0; - - subseg_set (s, frchainP->frch_subseg); + subseg_set (s, frchainP->frch_subseg); - /* This now gets called even if we had errors. In that case, - any alignment is meaningless, and, moreover, will look weird - if we are generating a listing. */ - if (!had_errors ()) + /* This now gets called even if we had errors. In that case, + any alignment is meaningless, and, moreover, will look weird + if we are generating a listing. */ + if (!had_errors ()) + { + alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP); + if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) + && now_seg->entsize) { - alignment = SUB_SEGMENT_ALIGN (now_seg, frchainP); - if ((bfd_get_section_flags (now_seg->owner, now_seg) & SEC_MERGE) - && now_seg->entsize) - { - unsigned int entsize = now_seg->entsize; - int entalign = 0; + unsigned int entsize = now_seg->entsize; + int entalign = 0; - while ((entsize & 1) == 0) - { - ++entalign; - entsize >>= 1; - } - if (entalign > alignment) - alignment = entalign; + while ((entsize & 1) == 0) + { + ++entalign; + entsize >>= 1; } + + if (entalign > alignment) + alignment = entalign; } + } - if (subseg_text_p (now_seg)) - frag_align_code (alignment, 0); - else - frag_align (alignment, 0, 0); + if (subseg_text_p (now_seg)) + frag_align_code (alignment, 0); + else + frag_align (alignment, 0, 0); - /* frag_align will have left a new frag. - Use this last frag for an empty ".fill". + /* frag_align will have left a new frag. + Use this last frag for an empty ".fill". - For this segment ... - Create a last frag. Do not leave a "being filled in frag". */ - frag_wane (frag_now); - frag_now->fr_fix = 0; - know (frag_now->fr_next == NULL); - } + For this segment ... + Create a last frag. Do not leave a "being filled in frag". */ + frag_wane (frag_now); + frag_now->fr_fix = 0; + know (frag_now->fr_next == NULL); } } +static void +subsegs_finish (void) +{ + asection *s; + + for (s = stdoutput->sections; s; s = s->next) + subsegs_finish_section (s); +} + +#ifdef OBJ_ELF +static void +create_obj_attrs_section (void) +{ + segT s; + char *p; + offsetT size; + const char *name; + + size = bfd_elf_obj_attr_size (stdoutput); + if (size) + { + name = get_elf_backend_data (stdoutput)->obj_attrs_section; + if (!name) + name = ".gnu.attributes"; + s = subseg_new (name, 0); + elf_section_type (s) + = get_elf_backend_data (stdoutput)->obj_attrs_section_type; + bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA); + frag_now_fix (); + p = frag_more (size); + bfd_elf_set_obj_attr_contents (stdoutput, (bfd_byte *)p, size); + + subsegs_finish_section (s); + relax_segment (seg_info (s)->frchainP->frch_root, s, 0); + size_seg (stdoutput, s, NULL); + } +} +#endif + /* Write the object file. */ void @@ -1843,6 +1878,11 @@ write_object_file (void) md_post_relax_hook; #endif +#ifdef OBJ_ELF + if (IS_ELF) + create_obj_attrs_section (); +#endif + #ifndef WORKING_DOT_WORD { struct broken_word *lie; |