This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Large data sections support
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Jan Hubicka <hubicka at ucw dot cz>
- Cc: binutils at sources dot redhat dot com, rth at redhat dot com
- Date: Sun, 12 Jun 2005 09:07:51 -0700
- Subject: Re: Large data sections support
- References: <20050612124135.GA15922@kam.mff.cuni.cz>
On Sun, Jun 12, 2005 at 02:41:35PM +0200, Jan Hubicka wrote:
> Hi,
> this patch adds support for .ldata/.lbbs and .lrodata as needed by x86-64 ABI
> draft for medium model. The idea actually came from rth after my initial patch
> to use .sdata/sbbs/srodata in medium model. The .l sections come last in the
> file and are allowed to exceed 2GB. (unlike for other architecutres the
> "small" datas are big enought for most of common use so using .l section
> instead of .s buys us some additional compatibility in between models and some
> nasty hacks to get GOT table before large datas).
>
> The patch was tested together with patches GCC to build medium model libraries
> on older version of GCC. I've just compiled it and run x86-64 testsuite on
> current. I am not sure if the approach of modifying global linker
> script sounds acceptable, but I don't see any negatives it would have
> for other architectures (as we do the same for sdata too).
>
> Does this look OK?
>
> Honza
>
> 2005-06-12 Jan Hubicka <jh@suse.cz>
> * elf.c (bfd_get_section_by_name): Add .ldata support.
> * elf64-x86-64.c (elf64_x86_64_add_symbol_hook): New.
> (elf_backend_add_symbol_hook): Define.
> * elf.sc: Add .ldata, .lbbs and .lrodata support.
Shouldn't you add some special sectons to elf64-x86-64.c to support
.ldata, .lbbs and .lrodata as output sections? Otherwise, you may
get wrong section attributes/flags.
>
> Index: bfd/elf.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf.c,v
> retrieving revision 1.242
> diff -c -3 -p -r1.242 elf.c
> *** bfd/elf.c 6 Sep 2004 20:55:22 -0000 1.242
> --- bfd/elf.c 8 Sep 2004 21:49:06 -0000
> *************** get_program_header_size (bfd *abfd)
> *** 4360,4365 ****
> --- 4360,4371 ----
> segs += 2;
> }
>
> + if (bfd_get_section_by_name (abfd, ".ldata") != NULL)
> + {
> + /* We need a large data area segment. */
> + ++segs;
> + }
> +
So ".lbss" won't introduce a new segment?
> if (bfd_get_section_by_name (abfd, ".dynamic") != NULL)
> {
> /* We need a PT_DYNAMIC segment. */
> Index: bfd/elf64-x86-64.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
> retrieving revision 1.83
> diff -c -3 -p -r1.83 elf64-x86-64.c
> *** bfd/elf64-x86-64.c 13 Aug 2004 03:15:59 -0000 1.83
> --- bfd/elf64-x86-64.c 8 Sep 2004 21:49:06 -0000
> *************** elf64_x86_64_check_relocs (bfd *abfd, st
> *** 973,978 ****
> --- 989,1029 ----
> 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,
> + Elf_Internal_Sym *sym, const char **namep,
> + flagword *flagsp, asection **secp, bfd_vma *valp)
> + {
> + if (sym->st_shndx == SHN_COMMON
> + && !info->relocatable
> + && sym->st_size > elf_gp_size (abfd))
> + {
> + /* Common symbols greater than -G nn bytes are
> + automatically put into .lbss. */
> +
> + asection *lcomm = bfd_get_section_by_name (abfd, ".lbss");
I assume different relocatons have to be used against those symbols
by compiler. Why can't compiler put those symbols into .lbss? You
don't want to linker put a normal symbol in .lbss since the relocations
may be wrong.
> +
> + 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;
> + }
> +
> +
> /* Return the section that should be marked against GC for a given
> relocation. */
>
> *************** elf64_x86_64_plt_sym_val (bfd_vma i, con
> *** 2809,2814 ****
> --- 2883,2889 ----
> #define bfd_elf64_bfd_reloc_type_lookup elf64_x86_64_reloc_type_lookup
>
> #define elf_backend_adjust_dynamic_symbol elf64_x86_64_adjust_dynamic_symbol
> + #define elf_backend_add_symbol_hook elf64_x86_64_add_symbol_hook
> #define elf_backend_check_relocs elf64_x86_64_check_relocs
> #define elf_backend_copy_indirect_symbol elf64_x86_64_copy_indirect_symbol
> #define elf_backend_create_dynamic_sections elf64_x86_64_create_dynamic_sections
> Index: ld/scripttempl/elf.sc
> ===================================================================
> RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
> retrieving revision 1.46
> diff -c -3 -p -r1.46 elf.sc
> *** ld/scripttempl/elf.sc 5 Jul 2004 20:00:13 -0000 1.46
> --- ld/scripttempl/elf.sc 8 Sep 2004 21:49:09 -0000
> ***************
> *** 69,74 ****
> --- 69,77 ----
> # .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
> + # .lrodata .gnu.linkonce.lr.foo
> #
> # Each of these can also have corresponding .rel.* and .rela.* sections.
>
> *************** if test -z "${NO_SMALL_DATA}"; then
> *** 141,146 ****
> --- 143,173 ----
> else
> NO_SMALL_DATA=" "
> fi
> + if test -z "${NO_LARGE_DATA}"; then
> + LBSS=".lbss ${RELOCATING-0} :
> + {
> + ${RELOCATING+PROVIDE (__lbss_start = .);}
> + ${RELOCATING+PROVIDE (___lbss_start = .);}
> + *(.dynlbss)
> + *(.lbss${RELOCATING+ .sbss.* .gnu.linkonce.sb.*})
> + *(.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.sbss${RELOCATING+ .rel.sbss.* .rel.gnu.linkonce.lb.*}) }
> + .rela.lbss ${RELOCATING-0} : { *(.rela.sbss${RELOCATING+ .rela.sbss.* .rela.gnu.linkonce.lb.*}) }"
> + else
> + NO_LARGE_DATA=" "
> + fi
> test -n "$SEPARATE_GOTPLT" && SEPARATE_GOTPLT=" "
> CTOR=".ctors ${CONSTRUCTING-0} :
> {
> *************** eval $COMBRELOCCAT <<EOF
> *** 258,263 ****
> --- 285,294 ----
> ${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}
> EOF
> if [ -n "$COMBRELOC" ]; then
> cat <<EOF
> *************** cat <<EOF
> *** 401,406 ****
> --- 432,440 ----
> ${RELOCATING+${OTHER_BSS_END_SYMBOLS}}
> ${RELOCATING+PROVIDE (end = .);}
> ${RELOCATING+${DATA_SEGMENT_END}}
> + ${LRODATA}
> + ${LDATA}
> + ${LBSS}
So the large data is beyound _end/end?
>
> /* Stabs debugging sections. */
> .stab 0 : { *(.stab) }
H.J.