[gPXE-devel] [PATCH 18/33] [linux] Add the linuxlibc platform

Piotr Jaroszyński p.jaroszynski at gmail.com
Sun Aug 15 18:59:23 EDT 2010


The linuxlibc platform is just like linux, but linked against libc.

Signed-off-by: Piotr Jaroszyński <p.jaroszynski at gmail.com>
---
 src/Makefile.housekeeping                      |    6 +-
 src/arch/i386/Makefile.linuxlibc               |    7 +
 src/arch/i386/scripts/linuxlibc.lds            |  193 ++++++++++++++++++++++
 src/arch/x86/Makefile.linuxlibc                |   29 ++++
 src/arch/x86/include/bits/linux_api_platform.h |   10 +
 src/arch/x86/prefix/linuxlibcprefix.c          |    1 +
 src/arch/x86/scripts/linuxlibc_symbols_remap   |   41 +++++
 src/arch/x86_64/Makefile.linuxlibc             |    4 +
 src/arch/x86_64/scripts/linuxlibc.lds          |  210 ++++++++++++++++++++++++
 src/config/defaults/linuxlibc.h                |   13 ++
 src/core/main.c                                |    6 +
 11 files changed, 517 insertions(+), 3 deletions(-)
 create mode 100644 src/arch/i386/Makefile.linuxlibc
 create mode 100644 src/arch/i386/scripts/linuxlibc.lds
 create mode 100644 src/arch/x86/Makefile.linuxlibc
 create mode 100644 src/arch/x86/prefix/linuxlibcprefix.c
 create mode 100644 src/arch/x86/scripts/linuxlibc_symbols_remap
 create mode 100644 src/arch/x86_64/Makefile.linuxlibc
 create mode 100644 src/arch/x86_64/scripts/linuxlibc.lds
 create mode 100644 src/config/defaults/linuxlibc.h

diff --git a/src/Makefile.housekeeping b/src/Makefile.housekeeping
index 09316a3..2a73ffb 100644
--- a/src/Makefile.housekeeping
+++ b/src/Makefile.housekeeping
@@ -295,7 +295,7 @@ arch :
 # Determine build platform
 DEFAULT_PLATFORM := pcbios
 PLATFORM	:= $(firstword $(BIN_PLATFORM) $(DEFAULT_PLATFORM))
-CFLAGS		+= -DPLATFORM=$(PLATFORM)
+CFLAGS		+= -DPLATFORM=$(PLATFORM) -DPLATFORM_$(PLATFORM)
 platform :
 	@$(ECHO) $(PLATFORM)
 
@@ -712,9 +712,9 @@ BUILD_ID_CMD	:= perl -e 'printf "0x%08x", int ( rand ( 0xffffffff ) );'
 # Build an intermediate object file from the objects required for the
 # specified target.
 #
-$(BIN)/%.tmp : $(BLIB) $(MAKEDEPS) $(LDSCRIPT)
+$(BIN)/%.tmp : $(BLIB) $(MAKEDEPS) $(LDSCRIPT) $(TGT_EXTRA_DEPS)
 	$(QM)$(ECHO) "  [LD] $@"
-	$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT) $(TGT_LD_FLAGS) $(BLIB) -o $@ \
+	$(Q)$(LD) $(LDFLAGS) -T $(LDSCRIPT) $(TGT_LD_FLAGS) $(BLIB) $(TGT_LD_FLAGS_POST) -o $@ \
 		--defsym _build_id=`$(BUILD_ID_CMD)` -Map $(BIN)/$*.tmp.map
 	$(Q)$(OBJDUMP) -ht $@ | $(PERL) $(SORTOBJDUMP) >> $(BIN)/$*.tmp.map
 
diff --git a/src/arch/i386/Makefile.linuxlibc b/src/arch/i386/Makefile.linuxlibc
new file mode 100644
index 0000000..6654ad7
--- /dev/null
+++ b/src/arch/i386/Makefile.linuxlibc
@@ -0,0 +1,7 @@
+LDSCRIPT = arch/i386/scripts/linuxlibc.lds
+
+# breaks stdlibs
+CFLAGS += -mregparm=0 -mno-rtd
+
+MAKEDEPS += arch/x86/Makefile.linuxlibc
+include arch/x86/Makefile.linuxlibc
diff --git a/src/arch/i386/scripts/linuxlibc.lds b/src/arch/i386/scripts/linuxlibc.lds
new file mode 100644
index 0000000..503c8bc
--- /dev/null
+++ b/src/arch/i386/scripts/linuxlibc.lds
@@ -0,0 +1,193 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386",
+              "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SEARCH_DIR("/usr/i386-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x08048000)); . = SEGMENT_START("text-segment", 0x08048000) + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rel.dyn        :
+    {
+      *(.rel.init)
+      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)
+      *(.rel.fini)
+      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)
+      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)
+      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)
+      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)
+      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)
+      *(.rel.ctors)
+      *(.rel.dtors)
+      *(.rel.got)
+      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)
+      *(.rel.ifunc)
+    }
+  .rel.plt        :
+    {
+      *(.rel.plt)
+      PROVIDE_HIDDEN (__rel_iplt_start = .);
+      *(.rel.iplt)
+      PROVIDE_HIDDEN (__rel_iplt_end = .);
+    }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0x90909090
+  .plt            : { *(.plt) *(.iplt) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0x90909090
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array     :
+  {
+     PROVIDE_HIDDEN (__init_array_start = .);
+     KEEP (*(SORT(.init_array.*)))
+     KEEP (*(.init_array))
+     PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array     :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) *(.igot) }
+  . = DATA_SEGMENT_RELRO_END (12, .);
+  .got.plt        : { *(.got.plt)  *(.igot.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+    *(SORT(.tbl.*))
+  }
+  .data1          : { *(.data1) }
+  _edata = .; PROVIDE (edata = .);
+  __bss_start = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(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.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 32 / 8 : 1);
+  }
+  . = ALIGN(32 / 8);
+  . = ALIGN(32 / 8);
+  _end = .; PROVIDE (end = .);
+  . = DATA_SEGMENT_END (.);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
diff --git a/src/arch/x86/Makefile.linuxlibc b/src/arch/x86/Makefile.linuxlibc
new file mode 100644
index 0000000..fceac28
--- /dev/null
+++ b/src/arch/x86/Makefile.linuxlibc
@@ -0,0 +1,29 @@
+MEDIA = linuxlibc
+
+INCDIRS += arch/x86/include/linux
+
+# stdlib objects that need to be passed before any other objects
+STDLIBS_BEGIN = $(BIN)/remapped_crt1.o $(BIN)/remapped_crti.o $(BIN)/remapped_crtbeginT.o
+# stdlib archives
+STDLIBS_LIBS = $(BIN)/remapped_libc.a $(BIN)/remapped_libgcc.a $(BIN)/remapped_libgcc_eh.a
+STDLIBS_LIBS_L = $(foreach lib, $(STDLIBS_LIBS), -l:$(lib))
+# stdlib objects that need to be passed at the end
+STDLIBS_END = $(BIN)/remapped_crtend.o $(BIN)/remapped_crtn.o
+
+SYMBOLS_REMAP = arch/x86/scripts/linuxlibc_symbols_remap
+
+# Redefine colliding stdlib symbols
+$(BIN)/remapped_% : $(SYMBOLS_REMAP)
+	$(QM)$(ECHO) "  [REMAP] $*"
+	$(Q)objcopy --redefine-syms=$(SYMBOLS_REMAP) $(shell gcc $(CFLAGS) --print-file-name $*) $@
+
+.PRECIOUS : $(BIN)/remapped_%
+
+TGT_EXTRA_DEPS += $(STDLIBS_BEGIN) $(STDLIBS_LIBS) $(STDLIBS_END)
+TGT_LD_FLAGS_PRE += -static $(STDLIBS_BEGIN)
+# use a group because the libs dep on each other
+TGT_LD_FLAGS_POST += --start-group $(STDLIBS_LIBS_L) --end-group $(STDLIBS_END)
+
+$(BIN)/%.linuxlibc : $(BIN)/%.linuxlibc.tmp
+	$(QM)$(ECHO) "  [FINISH] $@"
+	$(Q)cp -p $< $@
diff --git a/src/arch/x86/include/bits/linux_api_platform.h b/src/arch/x86/include/bits/linux_api_platform.h
index 4a9ced5..e4bca73 100644
--- a/src/arch/x86/include/bits/linux_api_platform.h
+++ b/src/arch/x86/include/bits/linux_api_platform.h
@@ -1,6 +1,16 @@
 #ifndef _LINUX_API_PLATFORM_H
 #define _LINUX_API_PLATFORM_H
 
+#ifndef PLATFORM_linuxlibc
+
 extern int linux_errno;
 
+#else
+
+/* __errno_location is defined by stdlibs */
+extern int * __errno_location(void);
+#define linux_errno (*__errno_location ())
+
+#endif
+
 #endif /* _LINUX_API_PLATFORM_H */
diff --git a/src/arch/x86/prefix/linuxlibcprefix.c b/src/arch/x86/prefix/linuxlibcprefix.c
new file mode 100644
index 0000000..9ca5ecd
--- /dev/null
+++ b/src/arch/x86/prefix/linuxlibcprefix.c
@@ -0,0 +1 @@
+/* No prefix code needed as stdlibs are taking care of the initialization */
diff --git a/src/arch/x86/scripts/linuxlibc_symbols_remap b/src/arch/x86/scripts/linuxlibc_symbols_remap
new file mode 100644
index 0000000..4197acd
--- /dev/null
+++ b/src/arch/x86/scripts/linuxlibc_symbols_remap
@@ -0,0 +1,41 @@
+access linux_access
+basename linux_basename
+close linux_close
+dirname linux_dirname
+execv linux_execv
+fcntl linux_fcntl
+free linux_free
+getchar linux_getchar
+getopt_long linux_getopt_long
+gettimeofday linux_gettimeofday
+getuid linux_getuid
+inet_ntoa linux_inet_ntoa
+ioctl linux_ioctl
+iopl linux_iopl
+isspace linux_isspace
+lseek linux_lseek
+malloc linux_malloc
+memcmp linux_memcmp
+mmap linux_mmap
+mremap linux_mremap
+munmap linux_munmap
+open linux_open
+poll linux_poll
+printf linux_printf
+putchar linux_putchar
+read linux_read
+realloc linux_realloc
+strcat linux_strcat
+strchr linux_strchr
+strcmp linux_strcmp
+strcpy linux_strcpy
+strerror linux_strerror
+strncpy linux_strncpy
+strrchr linux_strrchr
+strstr linux_strstr
+strtoul linux_strtoul
+strtoull linux_strtoull
+syscall linux_syscall
+usleep linux_usleep
+vprintf linux_vprintf
+write linux_write
diff --git a/src/arch/x86_64/Makefile.linuxlibc b/src/arch/x86_64/Makefile.linuxlibc
new file mode 100644
index 0000000..68312b8
--- /dev/null
+++ b/src/arch/x86_64/Makefile.linuxlibc
@@ -0,0 +1,4 @@
+LDSCRIPT = arch/x86_64/scripts/linuxlibc.lds
+
+MAKEDEPS += arch/x86/Makefile.linuxlibc
+include arch/x86/Makefile.linuxlibc
diff --git a/src/arch/x86_64/scripts/linuxlibc.lds b/src/arch/x86_64/scripts/linuxlibc.lds
new file mode 100644
index 0000000..d7e0c37
--- /dev/null
+++ b/src/arch/x86_64/scripts/linuxlibc.lds
@@ -0,0 +1,210 @@
+OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
+              "elf64-x86-64")
+OUTPUT_ARCH(i386:x86-64)
+ENTRY(_start)
+SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
+  .interp         : { *(.interp) }
+  .note.gnu.build-id : { *(.note.gnu.build-id) }
+  .hash           : { *(.hash) }
+  .gnu.hash       : { *(.gnu.hash) }
+  .dynsym         : { *(.dynsym) }
+  .dynstr         : { *(.dynstr) }
+  .gnu.version    : { *(.gnu.version) }
+  .gnu.version_d  : { *(.gnu.version_d) }
+  .gnu.version_r  : { *(.gnu.version_r) }
+  .rela.dyn       :
+    {
+      *(.rela.init)
+      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
+      *(.rela.fini)
+      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
+      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
+      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
+      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
+      *(.rela.ctors)
+      *(.rela.dtors)
+      *(.rela.got)
+      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
+      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
+      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
+      *(.rela.ifunc)
+    }
+  .rela.plt       :
+    {
+      *(.rela.plt)
+      PROVIDE_HIDDEN (__rela_iplt_start = .);
+      *(.rela.iplt)
+      PROVIDE_HIDDEN (__rela_iplt_end = .);
+    }
+  .init           :
+  {
+    KEEP (*(.init))
+  } =0x90909090
+  .plt            : { *(.plt) *(.iplt) }
+  .text           :
+  {
+    *(.text.unlikely .text.*_unlikely)
+    *(.text .stub .text.* .gnu.linkonce.t.*)
+    /* .gnu.warning sections are handled specially by elf32.em.  */
+    *(.gnu.warning)
+  } =0x90909090
+  .fini           :
+  {
+    KEEP (*(.fini))
+  } =0x90909090
+  PROVIDE (__etext = .);
+  PROVIDE (_etext = .);
+  PROVIDE (etext = .);
+  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
+  .rodata1        : { *(.rodata1) }
+  .eh_frame_hdr : { *(.eh_frame_hdr) }
+  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }
+  /* Adjust the address for the data segment.  We want to adjust up to
+     the same address within the page on the next page up.  */
+  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
+  /* Exception handling  */
+  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
+  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
+  /* Thread Local Storage sections  */
+  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
+  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
+  .preinit_array     :
+  {
+    PROVIDE_HIDDEN (__preinit_array_start = .);
+    KEEP (*(.preinit_array))
+    PROVIDE_HIDDEN (__preinit_array_end = .);
+  }
+  .init_array     :
+  {
+     PROVIDE_HIDDEN (__init_array_start = .);
+     KEEP (*(SORT(.init_array.*)))
+     KEEP (*(.init_array))
+     PROVIDE_HIDDEN (__init_array_end = .);
+  }
+  .fini_array     :
+  {
+    PROVIDE_HIDDEN (__fini_array_start = .);
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    PROVIDE_HIDDEN (__fini_array_end = .);
+  }
+  .ctors          :
+  {
+    /* gcc uses crtbegin.o to find the start of
+       the constructors, so we make sure it is
+       first.  Because this is a wildcard, it
+       doesn't matter if the user does not
+       actually link against crtbegin.o; the
+       linker won't look for a file to match a
+       wildcard.  The wildcard also means that it
+       doesn't matter which directory crtbegin.o
+       is in.  */
+    KEEP (*crtbegin.o(.ctors))
+    KEEP (*crtbegin?.o(.ctors))
+    /* We don't want to include the .ctor section from
+       the crtend.o file until after the sorted ctors.
+       The .ctor section from the crtend file contains the
+       end of ctors marker and it must be last */
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
+    KEEP (*(SORT(.ctors.*)))
+    KEEP (*(.ctors))
+  }
+  .dtors          :
+  {
+    KEEP (*crtbegin.o(.dtors))
+    KEEP (*crtbegin?.o(.dtors))
+    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
+    KEEP (*(SORT(.dtors.*)))
+    KEEP (*(.dtors))
+  }
+  .jcr            : { KEEP (*(.jcr)) }
+  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }
+  .dynamic        : { *(.dynamic) }
+  .got            : { *(.got) *(.igot) }
+  . = DATA_SEGMENT_RELRO_END (24, .);
+  .got.plt        : { *(.got.plt)  *(.igot.plt) }
+  .data           :
+  {
+    *(.data .data.* .gnu.linkonce.d.*)
+    SORT(CONSTRUCTORS)
+    *(SORT(.tbl.*))
+  }
+  .data1          : { *(.data1) }
+  _edata = .; PROVIDE (edata = .);
+  __bss_start = .;
+  .bss            :
+  {
+   *(.dynbss)
+   *(.bss .bss.* .gnu.linkonce.b.*)
+   *(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.
+      FIXME: Why do we need it? When there is no .bss section, we don't
+      pad the .data section.  */
+   . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  .lbss   :
+  {
+    *(.dynlbss)
+    *(.lbss .lbss.* .gnu.linkonce.lb.*)
+    *(LARGE_COMMON)
+  }
+  . = ALIGN(64 / 8);
+  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
+  }
+  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
+  {
+    *(.ldata .ldata.* .gnu.linkonce.l.*)
+    . = ALIGN(. != 0 ? 64 / 8 : 1);
+  }
+  . = ALIGN(64 / 8);
+  _end = .; PROVIDE (end = .);
+  . = DATA_SEGMENT_END (.);
+  /* Stabs debugging sections.  */
+  .stab          0 : { *(.stab) }
+  .stabstr       0 : { *(.stabstr) }
+  .stab.excl     0 : { *(.stab.excl) }
+  .stab.exclstr  0 : { *(.stab.exclstr) }
+  .stab.index    0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment       0 : { *(.comment) }
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+  /* SGI/MIPS DWARF 2 extensions */
+  .debug_weaknames 0 : { *(.debug_weaknames) }
+  .debug_funcnames 0 : { *(.debug_funcnames) }
+  .debug_typenames 0 : { *(.debug_typenames) }
+  .debug_varnames  0 : { *(.debug_varnames) }
+  /* DWARF 3 */
+  .debug_pubtypes 0 : { *(.debug_pubtypes) }
+  .debug_ranges   0 : { *(.debug_ranges) }
+  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+}
diff --git a/src/config/defaults/linuxlibc.h b/src/config/defaults/linuxlibc.h
new file mode 100644
index 0000000..5f85824
--- /dev/null
+++ b/src/config/defaults/linuxlibc.h
@@ -0,0 +1,13 @@
+#ifndef CONFIG_DEFAULTS_LINUXLIBC_H
+#define CONFIG_DEFAULTS_LINUXLIBC_H
+
+/** @file
+ *
+ * Configuration defaults for linuxlibc
+ *
+ */
+
+/* Use linux defaults */
+#include <config/defaults/linux.h>
+
+#endif /* CONFIG_DEFAULTS_LINUXLIBC_H */
diff --git a/src/core/main.c b/src/core/main.c
index 36e6b02..48cebc2 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <gpxe/image.h>
 #include <usr/autoboot.h>
 #include <config/general.h>
+#include <hci/linux_args.h>
 
 #define NORMAL	"\033[0m"
 #define BOLD	"\033[1m"
@@ -32,7 +33,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
  *
  * @ret rc		Return status code
  */
+#ifdef PLATFORM_linuxlibc
+__asmcall int main ( int argc, char ** argv ) {
+	save_args ( argc, argv );
+#else
 __asmcall int main ( void ) {
+#endif
 	struct feature *feature;
 	struct image *image;
 
-- 
1.7.1



More information about the gPXE-devel mailing list