tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Linking C++
Kamil Rytarowski <n54%gmx.com@localhost> wrote:
>On 24.10.2019 01:20, Robert Swindells wrote:
>>
>> Kamil Rytarowski <n54%gmx.com@localhost> wrote:
>>> On 23.10.2019 19:28, Robert Swindells wrote:
>>>>
>>>> There is a restriction in our ld.elf_so that it can only load two
>>>> segments.
>>>
>>> Please test the patch from:
>>>
>>> http://mail-index.netbsd.org/tech-toolchain/2019/01/06/msg003368.html
>>
>> The patch works for me.
>>
>> Would something like this get into NetBSD-9 ?
>
>Unless we will get a patch with a better version, I plan to land it
>after 2 weeks and pull-request to -9.
>
>BTW. Please share your rebased version.
Patch attached. It hasn't really changed, just the context around one
of the chunks.
Index: map_object.c
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/map_object.c,v
retrieving revision 1.60
diff -u -r1.60 map_object.c
--- map_object.c 6 Jan 2019 19:44:54 -0000 1.60
+++ map_object.c 24 Oct 2019 10:35:52 -0000
@@ -71,7 +71,7 @@
#endif
size_t phsize;
Elf_Phdr *phlimit;
- Elf_Phdr *segs[2];
+ Elf_Phdr *segs[3];
int nsegs;
caddr_t mapbase = MAP_FAILED;
size_t mapsize = 0;
@@ -80,8 +80,6 @@
Elf_Addr base_alignment;
Elf_Addr base_vaddr;
Elf_Addr base_vlimit;
- Elf_Addr text_vlimit;
- int text_flags;
void *base_addr;
Elf_Off data_offset;
Elf_Addr data_vaddr;
@@ -93,14 +91,19 @@
#endif
Elf_Addr phdr_vaddr;
size_t phdr_memsz;
+#if 0
caddr_t gap_addr;
size_t gap_size;
+#endif
int i;
#ifdef RTLD_LOADER
Elf_Addr clear_vaddr;
caddr_t clear_addr;
size_t nclear;
#endif
+ Elf_Addr bss_vaddr;
+ caddr_t bss_addr;
+ Elf_Addr bss_vlimit;
#ifdef GNU_RELRO
Elf_Addr relro_page;
size_t relro_size;
@@ -191,7 +194,7 @@
break;
case PT_LOAD:
- if (nsegs < 2)
+ if (nsegs < 3)
segs[nsegs] = phdr;
++nsegs;
@@ -242,7 +245,7 @@
_rtld_error("%s: not dynamically linked", path);
goto bad;
}
- if (nsegs != 2) {
+ if (nsegs < 0 || nsegs > 3) {
_rtld_error("%s: wrong number of segments (%d != 2)", path,
nsegs);
goto bad;
@@ -263,18 +266,8 @@
base_alignment = segs[0]->p_align;
base_offset = round_down(segs[0]->p_offset);
base_vaddr = round_down(segs[0]->p_vaddr);
- base_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_memsz);
- text_vlimit = round_up(segs[0]->p_vaddr + segs[0]->p_memsz);
- text_flags = protflags(segs[0]->p_flags);
- data_offset = round_down(segs[1]->p_offset);
- data_vaddr = round_down(segs[1]->p_vaddr);
- data_vlimit = round_up(segs[1]->p_vaddr + segs[1]->p_filesz);
- data_flags = protflags(segs[1]->p_flags);
-#ifdef RTLD_LOADER
- clear_vaddr = segs[1]->p_vaddr + segs[1]->p_filesz;
-#endif
+ base_vlimit = round_up(segs[nsegs-1]->p_vaddr + segs[nsegs-1]->p_memsz);
- obj->textsize = text_vlimit - base_vaddr;
obj->vaddrbase = base_vaddr;
obj->isdynamic = ehdr->e_type == ET_DYN;
@@ -322,11 +315,13 @@
dbg(("%s: phdr %p phsize %zu (%s)", obj->path, obj->phdr, obj->phsize,
obj->phdr_loaded ? "loaded" : "allocated"));
+#if 0 /* TODO? */
/* Unmap header if it overlaps the first load section. */
if (base_offset < _rtld_pagesz) {
munmap(ehdr, _rtld_pagesz);
obj->ehdr = MAP_FAILED;
}
+#endif
/*
* Calculate log2 of the base section alignment.
@@ -347,7 +342,7 @@
}
#endif
mapsize = base_vlimit - base_vaddr;
- mapbase = mmap(base_addr, mapsize, text_flags,
+ mapbase = mmap(base_addr, mapsize, PROT_NONE, // was: text_flags,
mapflags | MAP_FILE | MAP_PRIVATE, fd, base_offset);
if (mapbase == MAP_FAILED) {
_rtld_error("mmap of entire address space failed: %s",
@@ -361,23 +356,51 @@
}
#endif
- /* Overlay the data segment onto the proper region. */
- data_addr = mapbase + (data_vaddr - base_vaddr);
- if (mmap(data_addr, data_vlimit - data_vaddr, data_flags,
- MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, data_offset) ==
- MAP_FAILED) {
- _rtld_error("mmap of data failed: %s", xstrerror(errno));
- goto bad;
- }
+ /* Overlay the individual segments onto the proper regions. */
+ for (i = 0; i < nsegs; i++) {
+ data_offset = round_down(segs[i]->p_offset);
+ data_vaddr = round_down(segs[i]->p_vaddr);
+ data_vlimit = round_up(segs[i]->p_vaddr + segs[i]->p_filesz);
+ data_flags = protflags(segs[i]->p_flags);
+
+ data_addr = mapbase + (data_vaddr - base_vaddr);
+ if (data_flags & PF_X) { /* text segment */
+ obj->textsize = data_vlimit - data_vaddr;
+ }
- /* Overlay the bss segment onto the proper region. */
- if (mmap(mapbase + data_vlimit - base_vaddr, base_vlimit - data_vlimit,
- data_flags, MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) ==
- MAP_FAILED) {
- _rtld_error("mmap of bss failed: %s", xstrerror(errno));
- goto bad;
+ if (mmap(data_addr, data_vlimit - data_vaddr, data_flags,
+ MAP_FILE | MAP_PRIVATE | MAP_FIXED, fd, data_offset) ==
+ MAP_FAILED) {
+ _rtld_error("mmap of data failed: %s", xstrerror(errno));
+ goto bad;
+ }
+
+ if (segs[i]->p_filesz != segs[i]->p_memsz) {
+#ifdef RTLD_LOADER
+ clear_vaddr = segs[i]->p_vaddr + segs[i]->p_filesz;
+
+ /* Clear any BSS in the last page of the data segment. */
+ clear_addr = mapbase + (clear_vaddr - base_vaddr);
+ if ((nclear = data_vlimit - clear_vaddr) > 0)
+ memset(clear_addr, 0, nclear);
+#endif
+
+ /* Overlay the bss segment onto the proper region. */
+ bss_vaddr = data_vlimit;
+ bss_addr = mapbase + (bss_vaddr - base_vaddr);
+ bss_vlimit = round_up(segs[i]->p_vaddr + segs[i]->p_memsz);
+ if (bss_vlimit > bss_vaddr) {
+ if (mmap(bss_addr, bss_vlimit - bss_vaddr, data_flags,
+ MAP_ANON | MAP_PRIVATE | MAP_FIXED, -1, 0) ==
+ MAP_FAILED) {
+ _rtld_error("mmap of bss failed: %s", xstrerror(errno));
+ goto bad;
+ }
+ }
+ }
}
+#if 0 /* TODO */
/* Unmap the gap between the text and data. */
gap_addr = mapbase + round_up(text_vlimit - base_vaddr);
gap_size = data_addr - gap_addr;
@@ -386,14 +409,6 @@
xstrerror(errno));
goto bad;
}
-
-#ifdef RTLD_LOADER
- /* Clear any BSS in the last page of the data segment. */
- clear_addr = mapbase + (clear_vaddr - base_vaddr);
- if ((nclear = data_vlimit - clear_vaddr) > 0)
- memset(clear_addr, 0, nclear);
-
- /* Non-file portion of BSS mapped above. */
#endif
#if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
Home |
Main Index |
Thread Index |
Old Index