PATCH: Support x86-64 large data sections
H. J. Lu
hjl@lucon.org
Mon Jun 27 20:05:00 GMT 2005
More information about the Binutils mailing list
Mon Jun 27 20:05:00 GMT 2005
- Previous message (by thread): PATCH: Support ps common sections
- Next message (by thread): x86-64 large data sections updated
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Fri, Jun 17, 2005 at 03:09:49PM +0200, Jan Hubicka wrote: > > On Fri, Jun 17, 2005 at 11:08:52AM +0200, Jan Hubicka wrote: > > > > > > 1) I am unsure how to get page alignment only when .lrosegment is > > > non-zero. I tried to play around with SIZEOF operator but I am not sure > > > if I can apply SIZEOF to the alignment before .lrodata that might (in > > > theory) change size of .lrodata due to alignments. > > > > > > > I have implemented the similar thing for another project. I will take a > > look after I fix the SHN issue. > > > > > 2) I am completely such with the SHN issue. I've dicussed this with > > > > I am working on it now. I will add a few functions to ELF backend to > > deal with it. I hope to have something very soon. > > Thanks a lot! (I will try to cleanup the GCC part of changes in meantime.) > Honza Here are 2 patches for x86-64 large data section support. One is the infrastructure for PS common symbols and the other is for x86-64 large data section. H.J. -------------- next part -------------- 2005-06-27 H.J. Lu <hongjiu.lu@intel.com> * elf-bfd.h (elf_backend_data): Add special_section, common_definition, common_section_index, common_section, and merge_symbol. (_bfd_elf_common_definition): New. (_bfd_elf_common_section_index): New. (_bfd_elf_common_section): New. * elf.c (elf_fake_sections): Don't clear sh_flags. * elflink.c (_bfd_elf_merge_symbol): Call backend merge_symbol if it is available. (is_global_data_symbol_definition): Call backend common_definition instead of checking SHN_COMMON. (elf_link_add_object_symbols): Likewise. (elf_link_output_extsym): Call backend common_section_index for common section index. (elf_link_input_bfd): Call backend special_section for unknown special section indices. (_bfd_elf_common_definition): New. (_bfd_elf_common_section_index): New. (_bfd_elf_common_section): New. * elfxx-target.h (elf_backend_common_definition): New. (elf_backend_common_section_index): New. (elf_backend_common_section): New. (elf_backend_special_section): New. (elf_backend_merge_symbol): New. (elfNN_bed): Initialize special_section, common_definition, common_section_index, common_section, and merge_symbol. * section.c (BFD_FAKE_SECTION): New. (STD_SECTION): Use it. * bfd-in2.h: Regenerated. --- bfd/elf-bfd.h.common 2005-06-27 10:05:29.908272947 -0700 +++ bfd/elf-bfd.h 2005-06-27 10:06:05.683368968 -0700 @@ -973,6 +973,33 @@ struct elf_backend_data see elf.c. */ bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *); + /* Return the special section where symbol is defined. */ + asection *(*special_section) (Elf_Internal_Sym *); + + /* Is symbol defined in common section? */ + bfd_boolean (*common_definition) (Elf_Internal_Sym *); + + /* Return a common section index for section. */ + unsigned int (*common_section_index) (asection *); + + /* Return a common section for section. */ + asection *(*common_section) (asection *); + + /* Return TRUE if we can merge 2 definitions. */ + bfd_boolean (*merge_symbol) (struct bfd_link_info *, + struct elf_link_hash_entry **, + struct elf_link_hash_entry *, + Elf_Internal_Sym *, asection **, + bfd_vma *, unsigned int *, + bfd_boolean *, bfd_boolean *, + bfd_boolean *, bfd_boolean *, + bfd_boolean *, bfd_boolean *, + bfd_boolean *, bfd_boolean *, + bfd *, asection **, + bfd_boolean *, bfd_boolean *, + bfd_boolean *, bfd_boolean *, + bfd *, asection **); + /* Used to handle bad SHF_LINK_ORDER input. */ bfd_error_handler_type link_order_error_handler; @@ -1747,6 +1774,15 @@ extern int bfd_elf_link_record_local_dyn extern bfd_boolean _bfd_elf_close_and_cleanup (bfd *); +extern bfd_boolean _bfd_elf_common_definition + (Elf_Internal_Sym *); + +extern unsigned int _bfd_elf_common_section_index + (asection *); + +extern asection *_bfd_elf_common_section + (asection *); + extern void _bfd_dwarf2_cleanup_debug_info (bfd *); --- bfd/elf.c.common 2005-06-27 10:05:29.913272122 -0700 +++ bfd/elf.c 2005-06-27 10:05:29.935268492 -0700 @@ -2626,7 +2626,7 @@ elf_fake_sections (bfd *abfd, asection * return; } - this_hdr->sh_flags = 0; + /* Don't clear sh_flags. Assembler may set additional bits. */ if ((asect->flags & SEC_ALLOC) != 0 || asect->user_set_vma) --- bfd/elflink.c.common 2005-06-27 10:05:29.885276742 -0700 +++ bfd/elflink.c 2005-06-27 10:06:05.689367978 -0700 @@ -783,6 +783,7 @@ _bfd_elf_merge_symbol (bfd *abfd, bfd *oldbfd; bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon; bfd_boolean newweak, oldweak; + const struct elf_backend_data *bed; *skip = FALSE; *override = FALSE; @@ -960,6 +961,17 @@ _bfd_elf_merge_symbol (bfd *abfd, return FALSE; } + bed = get_elf_backend_data (abfd); + if (bed->merge_symbol + && !bed->merge_symbol (info, sym_hash, h, sym, psec, pvalue, + pold_alignment, skip, override, + type_change_ok, size_change_ok, + &newdyn, &newdef, &newdyncommon, &newweak, + abfd, &sec, + &olddyn, &olddef, &olddyncommon, &oldweak, + oldbfd, &oldsec)) + return FALSE; + /* We need to remember if a symbol has a definition in a dynamic object or is weak in all dynamic objects. Internal and hidden visibility will make it unavailable to dynamic objects. */ @@ -1200,7 +1212,7 @@ _bfd_elf_merge_symbol (bfd *abfd, newdef = FALSE; newdyncommon = FALSE; *pvalue = sym->st_size; - *psec = sec = bfd_com_section_ptr; + *psec = sec = bed->common_section (oldsec); *size_change_ok = TRUE; } @@ -2664,6 +2676,8 @@ static bfd_boolean is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED, Elf_Internal_Sym *sym) { + const struct elf_backend_data *bed; + /* Local symbols do not count, but target specific ones might. */ if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL && ELF_ST_BIND (sym->st_info) < STB_LOOS) @@ -2679,7 +2693,8 @@ is_global_data_symbol_definition (bfd *a /* If the symbol is defined in the common section, then it is a common definition and so does not count. */ - if (sym->st_shndx == SHN_COMMON) + bed = get_elf_backend_data (abfd); + if (bed->common_definition (sym)) return FALSE; /* If the symbol is in a target specific section then we @@ -3571,6 +3586,7 @@ elf_link_add_object_symbols (bfd *abfd, bfd_boolean type_change_ok; bfd_boolean new_weakdef; bfd_boolean override; + bfd_boolean common; unsigned int old_alignment; bfd *old_bfd; @@ -3580,6 +3596,7 @@ elf_link_add_object_symbols (bfd *abfd, sec = NULL; value = isym->st_value; *sym_hash = NULL; + common = bed->common_definition (isym); bind = ELF_ST_BIND (isym->st_info); if (bind == STB_LOCAL) @@ -3592,8 +3609,7 @@ elf_link_add_object_symbols (bfd *abfd, } else if (bind == STB_GLOBAL) { - if (isym->st_shndx != SHN_UNDEF - && isym->st_shndx != SHN_COMMON) + if (isym->st_shndx != SHN_UNDEF && !common) flags = BSF_GLOBAL; } else if (bind == STB_WEAK) @@ -3883,13 +3899,12 @@ elf_link_add_object_symbols (bfd *abfd, } /* Set the alignment of a common symbol. */ - if ((isym->st_shndx == SHN_COMMON - || bfd_is_com_section (sec)) + if ((common || bfd_is_com_section (sec)) && h->root.type == bfd_link_hash_common) { unsigned int align; - if (isym->st_shndx == SHN_COMMON) + if (common) align = bfd_log2 (isym->st_value); else { @@ -3915,7 +3930,7 @@ elf_link_add_object_symbols (bfd *abfd, definition or a common symbol is ignored due to the old normal definition. We need to make sure the maximum alignment is maintained. */ - if ((old_alignment || isym->st_shndx == SHN_COMMON) + if ((old_alignment || common) && h->root.type != bfd_link_hash_common) { unsigned int common_align; @@ -6528,7 +6543,7 @@ elf_link_output_extsym (struct elf_link_ case bfd_link_hash_common: input_sec = h->root.u.c.p->section; - sym.st_shndx = SHN_COMMON; + sym.st_shndx = bed->common_section_index (input_sec); sym.st_value = 1 << h->root.u.c.p->alignment_power; break; @@ -6882,6 +6897,8 @@ elf_link_input_bfd (struct elf_final_lin isec = bfd_abs_section_ptr; else if (isym->st_shndx == SHN_COMMON) isec = bfd_com_section_ptr; + else if (bed->special_section) + isec = bed->special_section (isym); else { /* Who knows? */ @@ -9906,3 +9923,21 @@ _bfd_elf_provide_section_bound_symbols ( if (do_end) bfd_elf_set_symbol (he, end_val); } + +bfd_boolean +_bfd_elf_common_definition (Elf_Internal_Sym *sym) +{ + return sym->st_shndx == SHN_COMMON; +} + +unsigned int +_bfd_elf_common_section_index (asection *sec ATTRIBUTE_UNUSED) +{ + return SHN_COMMON; +} + +asection * +_bfd_elf_common_section (asection *sec ATTRIBUTE_UNUSED) +{ + return bfd_com_section_ptr; +} --- bfd/elfxx-target.h.common 2005-06-27 10:05:29.920270967 -0700 +++ bfd/elfxx-target.h 2005-06-27 10:05:29.943267172 -0700 @@ -522,6 +522,26 @@ #define elf_backend_link_order_error_handler _bfd_default_error_handler #endif +#ifndef elf_backend_common_definition +#define elf_backend_common_definition _bfd_elf_common_definition +#endif + +#ifndef elf_backend_common_section_index +#define elf_backend_common_section_index _bfd_elf_common_section_index +#endif + +#ifndef elf_backend_common_section +#define elf_backend_common_section _bfd_elf_common_section +#endif + +#ifndef elf_backend_special_section +#define elf_backend_special_section NULL +#endif + +#ifndef elf_backend_merge_symbol +#define elf_backend_merge_symbol NULL +#endif + extern const struct elf_size_info _bfd_elfNN_size_info; #ifndef INCLUDED_TARGET_FILE @@ -591,6 +611,11 @@ static const struct elf_backend_data elf elf_backend_ecoff_debug_swap, elf_backend_bfd_from_remote_memory, elf_backend_plt_sym_val, + elf_backend_special_section, + elf_backend_common_definition, + elf_backend_common_section_index, + elf_backend_common_section, + elf_backend_merge_symbol, elf_backend_link_order_error_handler, elf_backend_relplt_name, ELF_MACHINE_ALT1, --- bfd/section.c.common 2005-05-18 10:37:28.000000000 -0700 +++ bfd/section.c 2005-06-27 10:05:29.945266842 -0700 @@ -634,6 +634,47 @@ CODE_FRAGMENT .#define bfd_section_removed_from_list(ABFD, S) \ . ((S)->next == NULL ? (ABFD)->section_last != (S) : (S)->next->prev != (S)) . +.#define BFD_FAKE_SECTION(SEC, FLAGS, SYM, SYM_PTR, NAME, IDX) \ +. {* name, id, index, next, prev, flags, user_set_vma, *} \ +. { NAME, IDX, 0, NULL, 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, has_gp_reloc, *} \ +. 0, 0, 0, 0, \ +. \ +. {* need_finalize_relax, reloc_done, *} \ +. 0, 0, \ +. \ +. {* vma, lma, size, rawsize *} \ +. 0, 0, 0, 0, \ +. \ +. {* output_offset, output_section, alignment_power, *} \ +. 0, (struct bfd_section *) &SEC, 0, \ +. \ +. {* relocation, orelocation, reloc_count, filepos, rel_filepos, *} \ +. NULL, NULL, 0, 0, 0, \ +. \ +. {* line_filepos, userdata, contents, lineno, lineno_count, *} \ +. 0, NULL, NULL, NULL, 0, \ +. \ +. {* entsize, kept_section, moving_line_filepos, *} \ +. 0, NULL, 0, \ +. \ +. {* target_index, used_by_bfd, constructor_chain, owner, *} \ +. 0, NULL, NULL, NULL, \ +. \ +. {* symbol, *} \ +. (struct bfd_symbol *) SYM, \ +. \ +. {* symbol_ptr_ptr, *} \ +. (struct bfd_symbol **) SYM_PTR, \ +. \ +. {* map_head, map_tail *} \ +. { NULL }, { NULL } \ +. } +. */ /* We use a macro to initialize the static asymbol structures because @@ -661,46 +702,8 @@ 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, prev, flags, user_set_vma, */ \ - { NAME, IDX, 0, NULL, 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, has_gp_reloc, */ \ - 0, 0, 0, 0, \ - \ - /* need_finalize_relax, reloc_done, */ \ - 0, 0, \ - \ - /* vma, lma, size, rawsize */ \ - 0, 0, 0, 0, \ - \ - /* output_offset, output_section, alignment_power, */ \ - 0, (struct bfd_section *) &SEC, 0, \ - \ - /* relocation, orelocation, reloc_count, filepos, rel_filepos, */ \ - NULL, NULL, 0, 0, 0, \ - \ - /* line_filepos, userdata, contents, lineno, lineno_count, */ \ - 0, NULL, NULL, NULL, 0, \ - \ - /* entsize, kept_section, moving_line_filepos, */ \ - 0, NULL, 0, \ - \ - /* target_index, used_by_bfd, constructor_chain, owner, */ \ - 0, NULL, NULL, NULL, \ - \ - /* symbol, */ \ - (struct bfd_symbol *) &global_syms[IDX], \ - \ - /* symbol_ptr_ptr, */ \ - (struct bfd_symbol **) &SYM, \ - \ - /* map_head, map_tail */ \ - { NULL }, { NULL } \ - } + asection SEC = BFD_FAKE_SECTION(SEC, FLAGS, &global_syms[IDX], &SYM, \ + NAME, IDX) STD_SECTION (bfd_com_section, SEC_IS_COMMON, bfd_com_symbol, BFD_COM_SECTION_NAME, 0); -------------- next part -------------- bfd/ 2005-06-27 Jan Hubicka <jh@suse.cz> H.J. Lu <hongjiu.lu@intel.com> * elf-bfd.h (_bfd_elf_large_com_section): New. * elf.c (_bfd_elf_large_com_section): New. Defined. * elf64-x86-64.c (elf64_x86_64_add_symbol_hook): New. (elf64_x86_64_elf_section_from_bfd_section): New. (elf64_x86_64_symbol_processing): New. (elf64_x86_64_common_definition): New. (elf64_x86_64_common_section_index): New. (elf64_x86_64_common_section): New. (elf64_x86_64_merge_symbol): New. (elf64_x86_64_additional_program_headers): New. (elf64_special_sections_l): New. (elf64_special_sections_g): New. (elf64_x86_64_elf_special_sections): New. (elf_backend_section_from_bfd_section): New. Defined. (elf_backend_add_symbol_hook): Likewise. (elf_backend_common_section_index): Likewise. (elf_backend_common_section): Likewise. (elf_backend_common_definition): Likewise. (elf_backend_merge_symbol): Likewise. (elf_backend_special_sections): Likewise. (elf_backend_additional_program_headers): Likewise. binutils/ 2005-06-27 H.J. Lu <hongjiu.lu@intel.com> * readelf.c (dump_relocations): Handle SHN_X86_64_LCOMMON. (get_symbol_index_type): Likewise. (get_elf_section_flags): Handle SHF_X86_64_LARGE. gas/ 2005-06-27 Jan Hubicka <jh@suse.cz> H.J. Lu <hongjiu.lu@intel.com> * config/obj-elf.c (elf_common_parse): Make it global. * config/obj-elf.h (elf_common_parse): New. * config/tc-i386.c (handle_large_common): New. (md_pseudo_table): Add "largecomm". (x86_64_section_letter): New. (x86_64_section_word): New. * config/tc-i386.h (x86_64_section_word): New. (x86_64_section_letter): New. (md_elf_section_letter): New. Defined. (md_elf_section_word): Likewise. include/elf/ 2005-06-27 Jan Hubicka <jh@suse.cz> * x86-64.h (SHN_X86_64_LCOMMON): New. (SHF_X86_64_LARGE): New. ld/ 2005-06-27 Jan Hubicka <jh@suse.cz> H.J. Lu <hongjiu.lu@intel.com> * emulparams/elf_x86_64.sh (LARGE_SECTIONS): New. * scripttempl/elf.sc: Updated for large section support. --- binutils/bfd/elf-bfd.h.large 2005-06-27 12:26:42.000000000 -0700 +++ binutils/bfd/elf-bfd.h 2005-06-27 12:26:42.000000000 -0700 @@ -1843,6 +1843,9 @@ extern bfd *_bfd_elf64_bfd_from_remote_m (bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep, int (*target_read_memory) (bfd_vma, bfd_byte *, int)); +/* Large common section. */ +extern asection _bfd_elf_large_com_section; + /* SH ELF specific routine. */ extern bfd_boolean _sh_elf_set_mach_from_flags --- binutils/bfd/elf.c.large 2005-06-27 12:26:42.000000000 -0700 +++ binutils/bfd/elf.c 2005-06-27 12:26:42.000000000 -0700 @@ -8410,3 +8410,9 @@ done: return result; } + +/* It is only used by x86-64 so far. */ +asection _bfd_elf_large_com_section + = BFD_FAKE_SECTION (_bfd_elf_large_com_section, + SEC_IS_COMMON, NULL, NULL, "LARGE_COMMON", + 0); --- binutils/bfd/elf64-x86-64.c.large 2005-06-27 12:26:42.000000000 -0700 +++ binutils/bfd/elf64-x86-64.c 2005-06-27 12:51:13.460476376 -0700 @@ -2900,6 +2900,209 @@ elf64_x86_64_section_from_shdr (bfd *abf return TRUE; } +/* Hook called by the linker routine which adds symbols from an object + file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead + of .bss. */ + +static bfd_boolean +elf64_x86_64_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, bfd_vma *valp) +{ + asection *lcomm; + + switch (sym->st_shndx) + { + case SHN_X86_64_LCOMMON: + lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON"); + if (lcomm == NULL) + { + lcomm = bfd_make_section_with_flags (abfd, + "LARGE_COMMON", + (SEC_ALLOC + | SEC_IS_COMMON + | SEC_LINKER_CREATED)); + if (lcomm == NULL) + return FALSE; + elf_section_flags (lcomm) |= SHF_X86_64_LARGE; + } + *secp = lcomm; + *valp = sym->st_size; + break; + } + return TRUE; +} + + +/* Given a BFD section, try to locate the corresponding ELF section + index. */ + +static bfd_boolean +elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, int *index) +{ + if (sec == &_bfd_elf_large_com_section) + { + *index = SHN_X86_64_LCOMMON; + return TRUE; + } + return FALSE; +} + +/* Process a symbol. */ + +static void +elf64_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym; + + switch (elfsym->internal_elf_sym.st_shndx) + { + case SHN_X86_64_LCOMMON: + asym->section = &_bfd_elf_large_com_section; + asym->value = elfsym->internal_elf_sym.st_size; + /* Common symbol doesn't set BSF_GLOBAL. */ + asym->flags &= ~BSF_GLOBAL; + break; + } +} + +static bfd_boolean +elf64_x86_64_common_definition (Elf_Internal_Sym *sym) +{ + return (sym->st_shndx == SHN_COMMON + || sym->st_shndx == SHN_X86_64_LCOMMON); +} + +static unsigned int +elf64_x86_64_common_section_index (asection *sec) +{ + if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) + return SHN_COMMON; + else + return SHN_X86_64_LCOMMON; +} + +static asection * +elf64_x86_64_common_section (asection *sec) +{ + if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0) + return bfd_com_section_ptr; + else + return &_bfd_elf_large_com_section; +} + +static bfd_boolean +elf64_x86_64_merge_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct elf_link_hash_entry **sym_hash ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym ATTRIBUTE_UNUSED, + asection **psec, + bfd_vma *pvalue ATTRIBUTE_UNUSED, + unsigned int *pold_alignment ATTRIBUTE_UNUSED, + bfd_boolean *skip ATTRIBUTE_UNUSED, + bfd_boolean *override ATTRIBUTE_UNUSED, + bfd_boolean *type_change_ok ATTRIBUTE_UNUSED, + bfd_boolean *size_change_ok ATTRIBUTE_UNUSED, + bfd_boolean *newdef ATTRIBUTE_UNUSED, + bfd_boolean *newdyn, + bfd_boolean *newdyncommon ATTRIBUTE_UNUSED, + bfd_boolean *newweak ATTRIBUTE_UNUSED, + bfd *abfd ATTRIBUTE_UNUSED, + asection **sec, + bfd_boolean *olddef ATTRIBUTE_UNUSED, + bfd_boolean *olddyn, + bfd_boolean *olddyncommon ATTRIBUTE_UNUSED, + bfd_boolean *oldweak ATTRIBUTE_UNUSED, + bfd *oldbfd ATTRIBUTE_UNUSED, + asection **oldsec) +{ + /* A small common symbol and a large common symbol result in a small + common symbol. */ + if (!*olddyn + && h->root.type == bfd_link_hash_common + && !*newdyn + && bfd_is_com_section (*sec) + && *oldsec != *sec) + *psec = *sec = bfd_com_section_ptr; + + return TRUE; +} + +static int +elf64_x86_64_additional_program_headers (bfd *abfd) +{ + asection *s; + int count = 0; + + /* Check to see if we need a large readonly segment. */ + s = bfd_get_section_by_name (abfd, ".lrodata"); + if (s && (s->flags & SEC_LOAD)) + count++; + + /* Check to see if we need a large data segment. Since .lbss sections + is placed right after the .bss section, there should be no need for + a large data segment just because of .lbss. */ + s = bfd_get_section_by_name (abfd, ".ldata"); + if (s && (s->flags & SEC_LOAD)) + count++; + + return count; +} + +static struct bfd_elf_special_section const + elf64_special_sections_l[]= +{ + { ".lbss", 5, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, + { ".ldata", 6, -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, + { ".lrodata", 8, -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, + { NULL, 0, 0, 0, 0 } +}; +static struct bfd_elf_special_section const + elf64_special_sections_g[]= +{ + { ".gnu.linkonce.lb", 16, -2, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE}, + { ".gnu.linkonce.lr", 16, -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE}, + { ".gnu.linkonce.lt", 16, -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE}, + { NULL, 0, 0, 0, 0 } +}; + +struct bfd_elf_special_section const * + elf64_x86_64_elf_special_sections[27] = +{ + NULL, /* 'a' */ + NULL, /* 'b' */ + NULL, /* 'c' */ + NULL, /* 'd' */ + NULL, /* 'e' */ + NULL, /* 'f' */ + elf64_special_sections_g, /* 'g' */ + NULL, /* 'h' */ + NULL, /* 'i' */ + NULL, /* 'j' */ + NULL, /* 'k' */ + elf64_special_sections_l, /* 'l' */ + NULL, /* 'm' */ + NULL, /* 'n' */ + NULL, /* 'o' */ + NULL, /* 'p' */ + NULL, /* 'q' */ + NULL, /* 'r' */ + NULL, /* 's' */ + NULL, /* 't' */ + NULL, /* 'u' */ + NULL, /* 'v' */ + NULL, /* 'w' */ + NULL, /* 'x' */ + NULL, /* 'y' */ + NULL, /* 'z' */ + NULL /* other */ +}; + #define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec #define TARGET_LITTLE_NAME "elf64-x86-64" #define ELF_ARCH bfd_arch_i386 @@ -2941,4 +3144,23 @@ elf64_x86_64_section_from_shdr (bfd *abf #define elf_backend_section_from_shdr \ elf64_x86_64_section_from_shdr +#define elf_backend_section_from_bfd_section \ + elf64_x86_64_elf_section_from_bfd_section +#define elf_backend_add_symbol_hook \ + elf64_x86_64_add_symbol_hook +#define elf_backend_symbol_processing \ + elf64_x86_64_symbol_processing +#define elf_backend_common_section_index \ + elf64_x86_64_common_section_index +#define elf_backend_common_section \ + elf64_x86_64_common_section +#define elf_backend_common_definition \ + elf64_x86_64_common_definition +#define elf_backend_merge_symbol \ + elf64_x86_64_merge_symbol +#define elf_backend_special_sections \ + elf64_x86_64_elf_special_sections +#define elf_backend_additional_program_headers \ + elf64_x86_64_additional_program_headers + #include "elf64-target.h" --- binutils/binutils/readelf.c.large 2005-06-17 15:26:37.000000000 -0700 +++ binutils/binutils/readelf.c 2005-06-27 12:26:42.000000000 -0700 @@ -1348,6 +1348,9 @@ dump_relocations (FILE *file, sec_name = "ABS"; else if (psym->st_shndx == SHN_COMMON) sec_name = "COMMON"; + else if (elf_header.e_machine == EM_X86_64 + && psym->st_shndx == SHN_X86_64_LCOMMON) + sec_name = "LARGE_COMMON"; else if (elf_header.e_machine == EM_IA_64 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX && psym->st_shndx == SHN_IA_64_ANSI_COMMON) @@ -3781,7 +3784,10 @@ get_elf_section_flags (bfd_vma sh_flags) case SHF_TLS: *p = 'T'; break; default: - if (flag & SHF_MASKOS) + if (elf_header.e_machine == EM_X86_64 + && flag == SHF_X86_64_LARGE) + *p = 'l'; + else if (flag & SHF_MASKOS) { *p = 'o'; sh_flags &= ~ SHF_MASKOS; @@ -6690,6 +6696,9 @@ get_symbol_index_type (unsigned int type && elf_header.e_machine == EM_IA_64 && elf_header.e_ident[EI_OSABI] == ELFOSABI_HPUX) return "ANSI_COM"; + else if (elf_header.e_machine == EM_X86_64 + && type == SHN_X86_64_LCOMMON) + return "LARGE_COM"; else if (type >= SHN_LOPROC && type <= SHN_HIPROC) sprintf (buff, "PRC[0x%04x]", type); else if (type >= SHN_LOOS && type <= SHN_HIOS) --- binutils/gas/config/obj-elf.c.large 2005-05-05 07:44:47.000000000 -0700 +++ binutils/gas/config/obj-elf.c 2005-06-27 12:26:42.000000000 -0700 @@ -270,7 +270,7 @@ elf_file_symbol (const char *s, int appf /* Called from read.c:s_comm after we've parsed .comm symbol, size. Parse a possible alignment value. */ -static symbolS * +symbolS * elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) { addressT align = 0; --- binutils/gas/config/obj-elf.h.large 2005-05-05 07:44:47.000000000 -0700 +++ binutils/gas/config/obj-elf.h 2005-06-27 12:26:42.000000000 -0700 @@ -246,5 +246,7 @@ struct ecoff_extr; #endif extern void elf_ecoff_set_ext (symbolS *, struct ecoff_extr *); #endif +extern symbolS * elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, + addressT size); #endif /* _OBJ_ELF_H */ --- binutils/gas/config/tc-i386.c.large 2005-06-26 08:24:15.000000000 -0700 +++ binutils/gas/config/tc-i386.c 2005-06-27 12:26:42.000000000 -0700 @@ -305,6 +305,7 @@ static int allow_naked_reg = 0; leave, push, and pop instructions so that gcc has the same stack frame as in 32 bit mode. */ static char stackop_size = '\0'; +static void handle_large_common (int small ATTRIBUTE_UNUSED); /* Non-zero to optimize code alignment. */ int optimize_align_code = 1; @@ -463,6 +464,9 @@ const pseudo_typeS md_pseudo_table[] = {"att_syntax", set_intel_syntax, 0}, {"file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0}, {"loc", dwarf2_directive_loc, 0}, +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) + {"largecomm", handle_large_common, 0}, +#endif #ifdef TE_PE {"secrel32", pe_directive_secrel, 0}, #endif @@ -6917,3 +6921,44 @@ tc_pe_dwarf2_emit_offset (symbolS *symbo emit_expr (&expr, size); } #endif + +#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF) +/* For ELF on x86-64, add support for SHF_X86_64_LARGE. */ + +int +x86_64_section_letter (int letter, char **ptr_msg) +{ + if (flag_code == CODE_64BIT) + { + if (letter == 'l') + return SHF_X86_64_LARGE; + + *ptr_msg = _("Bad .section directive: want a,l,w,x,M,S,G,T in string"); + } + else + *ptr_msg = _("Bad .section directive: want a,w,x,M,S,G,T in string"); + return -1; +} + +int +x86_64_section_word (char *str, size_t len) +{ + if (len == 5 && flag_code == CODE_64BIT && strncmp (str, "large", 5) == 0) + return SHF_X86_64_LARGE; + + return -1; +} + +static void +handle_large_common (int small ATTRIBUTE_UNUSED) +{ + symbolS *symbolP = s_comm_internal (0, elf_common_parse); + + if (flag_code != CODE_64BIT) + { + as_warn (_(".largecomm supported only in 64bit mode, producing .comm")); + } + else if (symbolP) + S_SET_SEGMENT (symbolP, &_bfd_elf_large_com_section); +} +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */ --- binutils/gas/config/tc-i386.h.large 2005-06-08 07:12:41.000000000 -0700 +++ binutils/gas/config/tc-i386.h 2005-06-27 12:26:42.000000000 -0700 @@ -498,6 +498,12 @@ extern void tc_x86_frame_initial_instruc #define md_elf_section_type(str,len) i386_elf_section_type (str, len) extern int i386_elf_section_type PARAMS ((const char *, size_t len)); +/* Support for SHF_X86_64_LARGE */ +extern int x86_64_section_word PARAMS ((char *, size_t)); +extern int x86_64_section_letter PARAMS ((int letter, char **ptr_msg)); +#define md_elf_section_letter(LETTER, PTR_MSG) x86_64_section_letter (LETTER, PTR_MSG) +#define md_elf_section_word(STR, LEN) x86_64_section_word (STR, LEN) + #ifdef TE_PE #define O_secrel O_md1 --- binutils/include/elf/x86-64.h.large 2005-06-17 15:26:45.000000000 -0700 +++ binutils/include/elf/x86-64.h 2005-06-27 12:26:42.000000000 -0700 @@ -61,4 +61,9 @@ END_RELOC_NUMBERS (R_X86_64_max) #define SHT_X86_64_UNWIND 0x70000001 /* unwind information */ +/* Like SHN_COMMON but the symbol will be allocated in the .lbss + section. */ +#define SHN_X86_64_LCOMMON 0xff02 + +#define SHF_X86_64_LARGE 0x10000000 #endif --- binutils/ld/emulparams/elf_x86_64.sh.large 2005-06-27 12:26:42.000000000 -0700 +++ binutils/ld/emulparams/elf_x86_64.sh 2005-06-27 12:26:42.000000000 -0700 @@ -12,6 +12,7 @@ TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes GENERATE_PIE_SCRIPT=yes NO_SMALL_DATA=yes +LARGE_SECTIONS=yes SEPARATE_GOTPLT=24 if [ "x${host}" = "x${target}" ]; then --- binutils/ld/scripttempl/elf.sc.large 2005-06-10 09:00:30.000000000 -0700 +++ binutils/ld/scripttempl/elf.sc 2005-06-27 12:26:42.000000000 -0700 @@ -78,6 +78,9 @@ # .debug_info .gnu.linkonce.wi.foo # .tdata .gnu.linkonce.td.foo # .tbss .gnu.linkonce.tb.foo +# .lrodata .gnu.linkonce.lr.foo +# .ldata .gnu.linkonce.l.foo +# .lbss .gnu.linkonce.lb.foo # # Each of these can also have corresponding .rel.* and .rela.* sections. @@ -157,6 +160,31 @@ if test -z "${SDATA_GOT}"; then SDATA_GOT=" " fi fi +if test -n "${LARGE_SECTIONS}"; then + LBSS=" + .lbss ${RELOCATING-0} : + { + *(.dynlbss) + *(.lbss${RELOCATING+ .lbss.* .gnu.linkonce.lb.*}) + *(LARGE_COMMON) + }" + LARGE_SECTIONS=" + .lrodata ${RELOCATING-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} : + { + *(.lrodata${RELOCATING+ .lrodata.* .gnu.linkonce.lr.*}) + } + .ldata ${RELOCATING-0} ${RELOCATING+ALIGN(${MAXPAGESIZE}) + (. & (${MAXPAGESIZE} - 1))} : + { + *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*}) + ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);} + }" + REL_LDATA=".rel.ldata ${RELOCATING-0} : { *(.rel.ldata${RELOCATING+ .rel.ldata.* .rel.gnu.linkonce.l.*}) } + .rela.ldata ${RELOCATING-0} : { *(.rela.ldata${RELOCATING+ .rela.ldata.* .rela.gnu.linkonce.l.*}) }" + REL_LBSS=".rel.lbss ${RELOCATING-0} : { *(.rel.lbss${RELOCATING+ .rel.lbss.* .rel.gnu.linkonce.lb.*}) } + .rela.lbss ${RELOCATING-0} : { *(.rela.lbss${RELOCATING+ .rela.lbss.* .rela.gnu.linkonce.lb.*}) }" + REL_LRODATA=".rel.lrodata ${RELOCATING-0} : { *(.rel.lrodata${RELOCATING+ .rel.lrodata.* .rel.gnu.linkonce.lr.*}) } + .rela.lrodata ${RELOCATING-0} : { *(.rela.lrodata${RELOCATING+ .rela.lrodata.* .rela.gnu.linkonce.lr.*}) }" +fi test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" " CTOR=".ctors ${CONSTRUCTING-0} : { @@ -274,6 +302,9 @@ eval $COMBRELOCCAT <<EOF ${REL_SBSS2} .rel.bss ${RELOCATING-0} : { *(.rel.bss${RELOCATING+ .rel.bss.* .rel.gnu.linkonce.b.*}) } .rela.bss ${RELOCATING-0} : { *(.rela.bss${RELOCATING+ .rela.bss.* .rela.gnu.linkonce.b.*}) } + ${REL_LDATA} + ${REL_LBSS} + ${REL_LRODATA} EOF if [ -n "$COMBRELOC" ]; then cat <<EOF @@ -397,13 +428,17 @@ cat <<EOF *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ + .bss section disappears because there are no input sections. + FIXME: Why do we need it? When there is no .bss section, we don't + pad the .data section. */ ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);} } + ${LBSS} ${OTHER_BSS_SECTIONS} + ${RELOCATING+${OTHER_BSS_END_SYMBOLS}} + ${LARGE_SECTIONS} ${RELOCATING+. = ALIGN(${ALIGNMENT});} ${RELOCATING+_end = .;} - ${RELOCATING+${OTHER_BSS_END_SYMBOLS}} ${RELOCATING+PROVIDE (end = .);} ${RELOCATING+${DATA_SEGMENT_END}}
- Previous message (by thread): PATCH: Support ps common sections
- Next message (by thread): x86-64 large data sections updated
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list