This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: x86-64 large data sections updated
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Jan Hubicka <jh at suse dot cz>
- Cc: binutils at sources dot redhat dot com, rth at redhat dot com
- Date: Tue, 14 Jun 2005 18:19:02 -0700
- Subject: Re: x86-64 large data sections updated
- References: <20050614221315.GF19948@kam.mff.cuni.cz>
On Wed, Jun 15, 2005 at 12:13:15AM +0200, Jan Hubicka wrote:
> Index: bfd/elf64-x86-64.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
> retrieving revision 1.95
> diff -c -3 -p -r1.95 elf64-x86-64.c
> *** bfd/elf64-x86-64.c 17 May 2005 16:43:02 -0000 1.95
> --- bfd/elf64-x86-64.c 14 Jun 2005 21:50:20 -0000
> *************** elf64_x86_64_check_relocs (bfd *abfd, st
> *** 975,980 ****
> --- 991,1028 ----
> return TRUE;
> }
>
> + /* Hook called by the linker routine which adds symbols from an object
> + file. We use it to put .comm items in .lbss, and not .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)
> + {
> + if (sym->st_shndx == SHN_X86_64_LCOMMON)
> + {
> +
> + asection *lcomm = bfd_get_section_by_name (abfd, ".lbss");
> +
> + if (lcomm == NULL)
> + {
> + lcomm = bfd_make_section (abfd, ".lbss");
> + if (lcomm == NULL
> + || !bfd_set_section_flags (abfd, lcomm, (SEC_ALLOC
> + | SEC_IS_COMMON
> + | SEC_LINKER_CREATED)))
> + return FALSE;
> + }
> +
> + *secp = lcomm;
> + *valp = sym->st_size;
> + }
> +
> + return TRUE;
> + }
> +
> +
There are 2 problems:
1. You can't use .lbss section index in symbol table for
SHN_X86_64_LCOMMON. They are different. I don't think you can
set SEC_IS_COMMON for .lbss.
2. I don't think like creating a real section for common symbol. I know
MIPS does it this way. But it doesn't make it right. There is
SHN_X86_64_LCOMMON. It should be used in symbol table.
> /* Return the section that should be marked against GC for a given
> relocation. */
>
> *************** elf64_x86_64_section_from_shdr (bfd *abf
> *** 2839,2844 ****
> --- 2912,2985 ----
> return TRUE;
> }
>
> + /* Given a BFD section, try to locate the corresponding ELF section
> + index. This is used by both the 32-bit and the 64-bit ABI.
> + Actually, it's not clear to me that the 64-bit ABI supports these,
> + but for non-PIC objects we will certainly want support for at least
> + the .scommon section. */
> +
> + static bfd_boolean
> + elf64_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
> + asection *sec, int *retval)
> + {
> + if (strcmp (bfd_get_section_name (abfd, sec), ".lcommon") == 0
> + || strcmp (bfd_get_section_name (abfd, sec), ".lbss") == 0)
> + {
> + *retval = SHN_X86_64_LCOMMON;
> + return TRUE;
> + }
> + return FALSE;
> + }
There is no such a section .lcommon. SHN_X86_64_LCOMMON is not a
special section index which doesn't have a real section.
> Index: ld/scripttempl/elf.sc
> ===================================================================
> RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
> retrieving revision 1.59
> diff -c -3 -p -r1.59 elf.sc
> *** ld/scripttempl/elf.sc 10 Jun 2005 00:39:56 -0000 1.59
> --- ld/scripttempl/elf.sc 14 Jun 2005 21:50:21 -0000
> ***************
> *** 78,83 ****
> --- 78,85 ----
> # .debug_info .gnu.linkonce.wi.foo
> # .tdata .gnu.linkonce.td.foo
> # .tbss .gnu.linkonce.tb.foo
> + # .ldata .gnu.linkonce.l.foo
> + # .lbss .gnu.linkonce.lb.foo
You missed .lrodata/.gnu.linkonce.lr.foo.
> #
> # Each of these can also have corresponding .rel.* and .rela.* sections.
>
> *************** if test -z "${SDATA_GOT}"; then
> *** 157,162 ****
> --- 159,189 ----
> SDATA_GOT=" "
> fi
> fi
> + if test -z "${NO_LARGE_DATA}"; then
> + LBSS=".lbss ${RELOCATING-0} :
> + {
> + ${RELOCATING+PROVIDE (__lbss_start = .);}
> + ${RELOCATING+PROVIDE (___lbss_start = .);}
> + *(.dynlbss)
> + *(.lbss${RELOCATING+ .lbss.* .gnu.linkonce.lb.*})
> + *(.lcommon)
> + ${RELOCATING+PROVIDE (__lbss_end = .);}
> + ${RELOCATING+PROVIDE (___lbss_end = .);}
> + }"
> + LDATA="
> + .ldata ${RELOCATING-0} :
> + {
> + ${RELOCATING+${LDATA_START_SYMBOLS}}
> + *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
> + }"
> + LRODATA=".lrodata ${RELOCATING-0} : { *(.lrodata${RELOCATING+ .lrodata.* .gnu.linkonce.lr.*}) }"
> + 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.*}) }"
You need REL_LRODATA.
> + else
> + NO_LARGE_DATA=" "
> + fi
> test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" "
> CTOR=".ctors ${CONSTRUCTING-0} :
> {
> *************** eval $COMBRELOCCAT <<EOF
> *** 274,279 ****
> --- 301,310 ----
> ${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_LDATA2}
> + ${REL_LBSS2}
What are REL_LDATA2 and REL_LBSS2? You need REL_RODATA.
> EOF
> if [ -n "$COMBRELOC" ]; then
> cat <<EOF
> *************** cat <<EOF
> *** 401,406 ****
> --- 432,441 ----
> ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
> }
> ${OTHER_BSS_SECTIONS}
> + ${LBSS}
> + ${LDATA}
> + ${RELOCATING+. = ALIGN(${ALIGNMENT});}
> + ${LRODATA}
> ${RELOCATING+. = ALIGN(${ALIGNMENT});}
> ${RELOCATING+_end = .;}
> ${RELOCATING+${OTHER_BSS_END_SYMBOLS}}
I think aligment can use some tuning. You don't need to pad the .bss
section if there is a large data section after it. Also LRODATA may
need to be properly page aligned.
H.J.