-1

I am trying to link the Overlay example from the GDB reference manual. The example is targeting the d10v processor (not familiar with it) but I would like to demonstrate that the debugger works with overlays by compiling the example for the x86_64 or i386 architecture.

I tried importing the following section into the linker script. I first extracted the linker script using a technique I learned from StackOverflow.

$> gcc a.c -Wl,-verbose

I modified this linker script as such, adding the .ovly0{0-3} & .data0{0-3} sections as shown below:

/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
          "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/usr/local/x86_64-unknown-linux-gnu/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/x86_64-unknown-linux-gnu/lib"); 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) }

  .ovly0  0x1001000 : AT (0x408000) { foo.o(.text)  }
  .ovly1  0x1001000 : AT (0x409000) { bar.o(.text)  }
  .ovly2  0x1002000 : AT (0x40a000) { baz.o(.text)  }
  .ovly3  0x1002000 : AT (0x40b000) { grbx.o(.text) }
  .data00 0x2001000 : AT (0x40c000) { foo.o(.data)  }
  .data01 0x2001000 : AT (0x40d000) { bar.o(.data)  }
  .data02 0x2002000 : AT (0x40e000) { baz.o(.data)  }
  .data03 0x2002000 : AT (0x40f000) { grbx.o(.data) }

  .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))
  }
  .plt            : { *(.plt) *(.iplt) }

  .text           :
  {
    *(.text.unlikely .text.*_unlikely)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)

  }

  .fini           :
  {
    KEEP (*(.fini))
  }

  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.*) }
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges
  .exception_ranges*) }
  /* 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.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
  /* 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_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array))
    KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
    KEEP (*(.fini_array))
    KEEP (*(EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
    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.*)
    _ovly_table = .; 
    LONG(ABSOLUTE(ADDR(.ovly0)));
    LONG(SIZEOF(.ovly0));
    LONG(LOADADDR(.ovly0));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.ovly1)));
    LONG(SIZEOF(.ovly1));
    LONG(LOADADDR(.ovly1));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.ovly2)));
    LONG(SIZEOF(.ovly2));
    LONG(LOADADDR(.ovly2));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.ovly3)));
    LONG(SIZEOF(.ovly3));
    LONG(LOADADDR(.ovly3));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.data00)));
    LONG(SIZEOF(.data00));
    LONG(LOADADDR(.data00));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.data01)));
    LONG(SIZEOF(.data01));
    LONG(LOADADDR(.data01));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.data02)));
    LONG(SIZEOF(.data02));
    LONG(LOADADDR(.data02));
    LONG(0);
    LONG(ABSOLUTE(ADDR(.data03)));
    LONG(SIZEOF(.data03));
    LONG(LOADADDR(.data03));
    LONG(0);
    _novlys = .;
    LONG((_novlys - _ovly_table) / 16);
    SORT(CONSTRUCTORS)
  }
  .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_*) }

}

The relevant portion of this script is below:

  .ovly0  0x1001000 : AT (0x408000) { foo.o(.text)  }
  .ovly1  0x1001000 : AT (0x409000) { bar.o(.text)  }
  .ovly2  0x1002000 : AT (0x40a000) { baz.o(.text)  }
  .ovly3  0x1002000 : AT (0x40b000) { grbx.o(.text) }
  .data00 0x2001000 : AT (0x40c000) { foo.o(.data)  }
  .data01 0x2001000 : AT (0x40d000) { bar.o(.data)  }
  .data02 0x2002000 : AT (0x40e000) { baz.o(.data)  }
  .data03 0x2002000 : AT (0x40f000) { grbx.o(.data) }

When I use this script to compile the program I end up with an executable object which runs, but will SEGFAULT when attempting to load the overlay. What is interesting is that the OBJDUMP output appears to be correct, that the two functions 'foo' and 'bar' are both given the same VMA addresses (0x1001000) and each has its assigned Load Address.

Here is the relevant portion of the OBJDUMP:

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       0000001c  0000000000400318  0000000000400318  00000318  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  1 .note.ABI-tag 00000020  0000000000400334  0000000000400334  00000334  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  2 .note.gnu.build-id 00000024  0000000000400354  0000000000400354  00000354  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  3 .hash         00000030  0000000000400378  0000000000400378  00000378  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  4 .gnu.hash     0000001c  00000000004003a8  00000000004003a8  000003a8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  5 .dynsym       000000a8  00000000004003c8  00000000004003c8  000003c8  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  6 .dynstr       00000050  0000000000400470  0000000000400470  00000470  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  7 .gnu.version  0000000e  00000000004004c0  00000000004004c0  000004c0  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  8 .gnu.version_r 00000020  00000000004004d0  00000000004004d0  000004d0  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
  9 .ovly0        0000002a  0000000001001000  0000000000408000  00001000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 10 .ovly1        0000002a  0000000001001000  0000000000409000  00201000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 11 .ovly2        0000002a  0000000001002000  000000000040a000  00202000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 12 .ovly3        0000002a  0000000001002000  000000000040b000  00402000  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 13 .data00       00000004  0000000002001000  000000000040c000  00601000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 14 .data01       00000004  0000000002001000  000000000040d000  00801000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 15 .data02       00000004  0000000002002000  000000000040e000  00802000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 16 .data03       00000004  0000000002002000  000000000040f000  00a02000  2**2
                  CONTENTS, ALLOC, LOAD, DATA
 17 .rela.dyn     00000018  0000000002002008  000000000040f008  00a02008  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 18 .rela.plt     00000078  0000000002002020  000000000040f020  00a02020  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 19 .init         00000018  0000000002002098  000000000040f098  00a02098  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 20 .plt          00000060  00000000020020b0  000000000040f0b0  00a020b0  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 21 .text         00000558  0000000002002110  000000000040f110  00a02110  2**4
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 22 .fini         0000000e  0000000002002668  000000000040f668  00a02668  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
 23 .rodata       00000086  0000000002002678  000000000040f678  00a02678  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 24 .eh_frame_hdr 0000007c  0000000002002700  000000000040f700  00a02700  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 25 .eh_frame     000001e4  0000000002002780  000000000040f780  00a02780  2**3
                  CONTENTS, ALLOC, LOAD, READONLY, DATA
 26 .ctors        00000010  0000000002202e18  000000000060fe18  00c02e18  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 27 .dtors        00000010  0000000002202e28  000000000060fe28  00c02e28  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 28 .jcr          00000008  0000000002202e38  000000000060fe38  00c02e38  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 29 .dynamic      000001a0  0000000002202e40  000000000060fe40  00c02e40  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 30 .got          00000008  0000000002202fe0  000000000060ffe0  00c02fe0  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 31 .got.plt      00000040  0000000002202fe8  000000000060ffe8  00c02fe8  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 32 .data         00000094  0000000002203028  0000000000610028  00c03028  2**3
                  CONTENTS, ALLOC, LOAD, DATA
 33 .bss          00000010  00000000022030c0  00000000006100c0  00c030bc  2**3
                  ALLOC
 34 .comment      00000048  0000000000000000  0000000000000000  00c030bc  2**0
                  CONTENTS, READONLY
 35 .debug_aranges 00000120  0000000000000000  0000000000000000  00c03104  2**0
                  CONTENTS, READONLY, DEBUGGING
 36 .debug_pubnames 000000c7  0000000000000000  0000000000000000  00c03224  2**0
                  CONTENTS, READONLY, DEBUGGING
 37 .debug_info   000004eb  0000000000000000  0000000000000000  00c032eb  2**0
                  CONTENTS, READONLY, DEBUGGING
 38 .debug_abbrev 000002d6  0000000000000000  0000000000000000  00c037d6  2**0
                  CONTENTS, READONLY, DEBUGGING
 39 .debug_line   00000551  0000000000000000  0000000000000000  00c03aac  2**0
                  CONTENTS, READONLY, DEBUGGING
 40 .debug_str    0000016e  0000000000000000  0000000000000000  00c03ffd  2**0
                  CONTENTS, READONLY, DEBUGGING
 41 .debug_loc    00000344  0000000000000000  0000000000000000  00c0416b  2**0
                  CONTENTS, READONLY, DEBUGGING
 42 .debug_macinfo 0000f019  0000000000000000  0000000000000000  00c044af  2**0
                  CONTENTS, READONLY, DEBUGGING

I really would like to know if anyone has worked with the Overlay feature of the linker and if so, has anyone been able to create a demonstration of this? I need this for an embedded debugger I am working on.

I would appreciate any help in this area.

Thank you,

muman613

muman
  • 124
  • 6

1 Answers1

-1

First, I must admit I haven't thoroughly examined your linker script - perhaps you can try to simplify it, and present a minimal linker script that still contains your problem?

That said, according to http://www.scoberlin.de/content/media/http/informatik/gcc_docs/ld_3.html#SEC36 , the OVERLAY command is just a convenience command. Perhaps this helps you?

Overlay description

An overlay description provides an easy way to describe sections which are to be loaded as part of a single memory image but are to be run at the same memory address. At run time, some sort of overlay manager will copy the overlaid sections in and out of the runtime memory address as required, perhaps by simply manipulating addressing bits. This approach can be useful, for example, when a certain region of memory is faster than another.

Overlays are described using the OVERLAY command. The OVERLAY command is used within a SECTIONS command, like an output section description. The full syntax of the OVERLAY command is as follows:

Note that the OVERLAY command is just syntactic sugar, since everything it does can be done using the more basic commands. The above example could have been written identically as follows.

parvus
  • 4,939
  • 6
  • 32
  • 54