Alpine Linux Porting (一点六?)

这是个工具半残时,debug会很惨烈的故事Orz
既上次想要搬迁到host来用qemu-user加快测试节奏後,发现Alpine内的toolchain与host的,因为bintuils版本不一,导致DWARF2的资讯无法被host端解读,而没办法正常判读行号与位置。

几经尝试,最後决定重新在 host 端使用riscv-gnu-toolchain,在configure时,多加上 --enable-gdb 来开启gdb的support。在有了可用的gdb後,继续进行debug,
从debug 讯息中判读,得知程序是在清零 bss section时,memset()遇上存取系统认为不可存取的区域:

│   780                         if (ph->p_memsz > ph->p_filesz && (ph->p_flags&PF_W)) {         
│   781                                 size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;     
│   782                                 size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;            
│  >783                                 memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);        
│   784                                 if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)
│   785                                         goto error;                                     
│   786                         }                                                               
│   787                 }                                                                       
│   788                 for (i=0; ((size_t *)(base+dyn))[i]; i+=2)                              
└───────────────────────────────────────────────────────────────────────────────────────────────
remote Thread 1.243523 In: map_library                                                          
(gdb) down
#1  0x3f7b1b94 in map_library (fd=5, dso=0x3fffe458) at ldso/dynlink.c:783
(gdb) p base
$1 = (unsigned char *) 0x3f423000 "\177ELF\001\001\001"
(gdb) p/x ph->p_vaddr
$2 = 0x279a50
(gdb) p/x brk
$3 = 0x3f6c7708

其中这时可以开始怀疑是不是mmap的部份有出状况,於是一路step进去看,此时发现我们呼叫到了mmap:

│   28          #ifdef SYS_mmap2                                                              
│   29                  ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);    
│   30          #else                                                                         
│  >31                  ret = __syscall(SYS_mmap, start, len, prot, flags, fd, off);          
│   32          #endif                                                                        
│   33                  /* Fixup incorrect EPERM from kernel. */                              
│   34                  if (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED))
│   35                          ret = -ENOMEM;                                                
│   36                  return (void *)__syscall_ret(ret);                                    
│   37          }                                                                             
└─────────────────────────────────────────────────────────────────────────────────────────────
remote Thread 1.244285 In: __mmap                                                             
(gdb) ni

这时,我们回去对一下QEMU的linux-user/riscv/syscall32_nr.h

208 #define TARGET_NR_mmap2 222

这下,就有趣了。

这时我们来看一下mmap2的manual page:

The mmap2() system call provides the same interface as mmap(2), except that the final argument specifies the offset into the file in 4096-byte units
       (instead of bytes, as is done by mmap(2)).  This enables applications that use a 32-bit off_t to map large files (up to 2^44 bytes).

而目前我的musl source中,SYS_mmap被指向了mmap2,变成错的syscall symbol,被对上mmap2。
这点改正後,我们可以再继续作验证看看。


<<:  Day14:铁口直断

>>:  RestTemplate实作(二)(Day12)

Day25 - 区块链的「硬分岔」史

什麽是软分岔、硬分岔? 在链上,常见有两种分岔,一种最容易理解,就是网路时差带来「最长链」不同的情...

前言

你好,我是 ALPHA Camp 的 Bernard。感谢你来阅读我的文章。这次铁人赛我会针对「成为...

【从零开始的Swift开发心路历程-Day28】认识GCD多执行绪Part1

GCD(Grand Central Dispatch)是由苹果开发用来操作Thread的API 而在...

中阶魔法 - this 指向(二)

前情提要 上回提到魔法学姊艾草(鸟)在练习英文。 艾草:「This, These, That, Th...

Dungeon Mizarka 013

怪物实作 怪物是由多个子物件组合而成的,其阶层看起来可能会是如下所示 利用子物件达成其功能的分类,目...