From 3b22753a67cf616514de804ef6d5ed5e90a7d883 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Mon, 25 Jul 2005 15:41:08 +0000 Subject: [PATCH] bfd/ 2005-07-25 Jan Hubicka H.J. Lu * 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_x86_64_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-07-25 H.J. Lu * 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-07-25 Jan Hubicka H.J. Lu * config/obj-elf.c: Include "elf/x86-64.h" if TC_I386 is defined. (elf_com_section_ptr): New. (elf_begin): Set elf_com_section_ptr to bfd_com_section_ptr. (elf_common_parse): Make it global. Use elf_com_section_ptr instead of bfd_com_section_ptr. (obj_elf_change_section): Handle x86-64 large bss sections. * config/obj-elf.h (elf_com_section_ptr): New. (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-07-25 Jan Hubicka * x86-64.h (SHN_X86_64_LCOMMON): New. (SHF_X86_64_LARGE): New. ld/ 2005-07-25 Jan Hubicka H.J. Lu * emulparams/elf_x86_64.sh (LARGE_SECTIONS): New. * scripttempl/elf.sc: Updated for large section support. --- bfd/ChangeLog | 24 ++++++ bfd/elf-bfd.h | 3 + bfd/elf.c | 6 ++ bfd/elf64-x86-64.c | 194 ++++++++++++++++++++++++++++++++++++++++++++ binutils/ChangeLog | 6 ++ binutils/readelf.c | 11 ++- gas/ChangeLog | 24 ++++++ gas/config/obj-elf.c | 20 ++++- gas/config/obj-elf.h | 3 + gas/config/tc-i386.c | 72 ++++++++++++++++ gas/config/tc-i386.h | 6 ++ include/elf/ChangeLog | 5 ++ include/elf/x86-64.h | 5 ++ ld/ChangeLog | 7 ++ ld/emulparams/elf_x86_64.sh | 1 + ld/scripttempl/elf.sc | 39 ++++++++- 16 files changed, 421 insertions(+), 5 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 64d9817..e59ec83 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,27 @@ +2005-07-25 Jan Hubicka + H.J. Lu + + * 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_x86_64_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. + 2005-07-25 H.J. Lu * elf-bfd.h (elf_backend_data): Add common_definition, diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index f7bab5c..5aa62eb 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1834,6 +1834,9 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory (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 diff --git a/bfd/elf.c b/bfd/elf.c index 3e47b02..c61bf33 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -8456,3 +8456,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); diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 598d308..0502e58 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -2906,6 +2906,181 @@ elf64_x86_64_section_from_shdr (bfd *abfd, 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, + asection **psec ATTRIBUTE_UNUSED, + 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 normal common symbol and a large common symbol result in a + normal common symbol. If we see the normal symbol first, we + do nothing since the first one will be used. If we see the + large common symbol first, we need to change the large common + symbol to the normal common symbol. */ + if (!*olddyn + && h->root.type == bfd_link_hash_common + && !*newdyn + && bfd_is_com_section (*sec) + && *oldsec != *sec + && sym->st_shndx == SHN_COMMON + && (elf_section_flags (*oldsec) & SHF_X86_64_LARGE) != 0) + { + h->root.u.c.p->section = bfd_make_section_old_way (abfd, + "COMMON"); + h->root.u.c.p->section->flags = SEC_ALLOC; + } + + 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 const struct bfd_elf_special_section + elf64_x86_64_special_sections[]= +{ + { ".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}, + { ".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 } +}; + #define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec #define TARGET_LITTLE_NAME "elf64-x86-64" #define ELF_ARCH bfd_arch_i386 @@ -2946,4 +3121,23 @@ elf64_x86_64_section_from_shdr (bfd *abfd, #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_special_sections +#define elf_backend_additional_program_headers \ + elf64_x86_64_additional_program_headers + #include "elf64-target.h" diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 421a514..41dd004 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2005-07-25 H.J. Lu + + * readelf.c (dump_relocations): Handle SHN_X86_64_LCOMMON. + (get_symbol_index_type): Likewise. + (get_elf_section_flags): Handle SHF_X86_64_LARGE. + 2005-07-21 Eric Christopher * MAINTAINERS: Change affiliation. diff --git a/binutils/readelf.c b/binutils/readelf.c index 07493fe..8c1f6f6 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -1355,6 +1355,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) @@ -3789,7 +3792,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; @@ -6698,6 +6704,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) diff --git a/gas/ChangeLog b/gas/ChangeLog index 409349a..9ffaff5 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,27 @@ +2005-07-25 Jan Hubicka + H.J. Lu + + * config/obj-elf.c: Include "elf/x86-64.h" if TC_I386 is + defined. + (elf_com_section_ptr): New. + (elf_begin): Set elf_com_section_ptr to bfd_com_section_ptr. + (elf_common_parse): Make it global. Use elf_com_section_ptr + instead of bfd_com_section_ptr. + (obj_elf_change_section): Handle x86-64 large bss sections. + + * config/obj-elf.h (elf_com_section_ptr): New. + (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. + 2005-07-21 Ralf Corsepius * configure.tgt: Remove i386-*-rtemself*. diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index d015dab..43e0c97 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -53,6 +53,10 @@ #include "elf/i370.h" #endif +#ifdef TC_I386 +#include "elf/x86-64.h" +#endif + static void obj_elf_line (int); static void obj_elf_size (int); static void obj_elf_type (int); @@ -174,6 +178,8 @@ static const pseudo_typeS ecoff_debug_pseudo_table[] = /* This is called when the assembler starts. */ +asection *elf_com_section_ptr; + void elf_begin (void) { @@ -186,6 +192,7 @@ elf_begin (void) symbol_table_insert (section_symbol (s)); s = bfd_get_section_by_name (stdoutput, BSS_SECTION_NAME); symbol_table_insert (section_symbol (s)); + elf_com_section_ptr = bfd_com_section_ptr; } void @@ -270,7 +277,7 @@ elf_file_symbol (const char *s, int appfile) /* 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; @@ -334,7 +341,7 @@ elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, addressT size) S_SET_VALUE (symbolP, size); S_SET_ALIGN (symbolP, align); S_SET_EXTERNAL (symbolP); - S_SET_SEGMENT (symbolP, bfd_com_section_ptr); + S_SET_SEGMENT (symbolP, elf_com_section_ptr); } symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT; @@ -569,7 +576,16 @@ obj_elf_change_section (const char *name, .section .init_array,"aw",@progbits for __attribute__ ((section (".init_array"))). + "@progbits" is incorrect. Also for x86-64 large bss + sections, gcc, as of 2005-07-06, will emit + + .section .lbss,"aw",@progbits + "@progbits" is incorrect. */ +#ifdef TC_I386 + && (bed->s->arch_size != 64 + || !(ssect->attr & SHF_X86_64_LARGE)) +#endif && ssect->type != SHT_INIT_ARRAY && ssect->type != SHT_FINI_ARRAY && ssect->type != SHT_PREINIT_ARRAY) diff --git a/gas/config/obj-elf.h b/gas/config/obj-elf.h index 01c1598..629fc00 100644 --- a/gas/config/obj-elf.h +++ b/gas/config/obj-elf.h @@ -244,5 +244,8 @@ extern void elf_pop_insert (void); struct ecoff_extr; extern void elf_ecoff_set_ext (symbolS *, struct ecoff_extr *); #endif +extern asection *elf_com_section_ptr; +extern symbolS * elf_common_parse (int ignore ATTRIBUTE_UNUSED, symbolS *symbolP, + addressT size); #endif /* _OBJ_ELF_H */ diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 514ff4bf..df3a35b 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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; @@ -467,6 +468,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 @@ -6990,3 +6994,71 @@ tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size) 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) +{ + if (flag_code != CODE_64BIT) + { + s_comm_internal (0, elf_common_parse); + as_warn (_(".largecomm supported only in 64bit mode, producing .comm")); + } + else + { + static segT lbss_section; + asection *saved_com_section_ptr = elf_com_section_ptr; + asection *saved_bss_section = bss_section; + + if (lbss_section == NULL) + { + flagword applicable; + segT seg = now_seg; + subsegT subseg = now_subseg; + + /* The .lbss section is for local .largecomm symbols. */ + lbss_section = subseg_new (".lbss", 0); + applicable = bfd_applicable_section_flags (stdoutput); + bfd_set_section_flags (stdoutput, lbss_section, + applicable & SEC_ALLOC); + seg_info (lbss_section)->bss = 1; + + subseg_set (seg, subseg); + } + + elf_com_section_ptr = &_bfd_elf_large_com_section; + bss_section = lbss_section; + + s_comm_internal (0, elf_common_parse); + + elf_com_section_ptr = saved_com_section_ptr; + bss_section = saved_bss_section; + } +} +#endif /* OBJ_ELF || OBJ_MAYBE_ELF */ diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index 0bd0660..3796ae1 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -501,6 +501,12 @@ extern void tc_x86_frame_initial_instructions PARAMS ((void)); #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 diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 1822b40..2947b66 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,8 @@ +2005-07-25 Jan Hubicka + + * x86-64.h (SHN_X86_64_LCOMMON): New. + (SHF_X86_64_LARGE): New. + 2005-07-20 Kazuhiro Inaoka * m32r.h (R_M32R_REL32): Added. diff --git a/include/elf/x86-64.h b/include/elf/x86-64.h index d83fc20..309be6b 100644 --- a/include/elf/x86-64.h +++ b/include/elf/x86-64.h @@ -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 diff --git a/ld/ChangeLog b/ld/ChangeLog index 09f6bdc..460fb39 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,10 @@ +2005-07-25 Jan Hubicka + H.J. Lu + + * emulparams/elf_x86_64.sh (LARGE_SECTIONS): New. + + * scripttempl/elf.sc: Updated for large section support. + 2005-07-21 Ralf Corsepius * configure.tgt: Remove i[3-7]86-*-rtemself*. diff --git a/ld/emulparams/elf_x86_64.sh b/ld/emulparams/elf_x86_64.sh index 172b4b1..35240df 100644 --- a/ld/emulparams/elf_x86_64.sh +++ b/ld/emulparams/elf_x86_64.sh @@ -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 diff --git a/ld/scripttempl/elf.sc b/ld/scripttempl/elf.sc index 2d92e3a..e1ac9e6 100644 --- a/ld/scripttempl/elf.sc +++ b/ld/scripttempl/elf.sc @@ -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 <