This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Large data sections support


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]