Android-- bionic介绍

Android-- bionic介绍


小组人员移植ntfs-3g碰到lseek越界问题,经过查证其使用了llseek函数导致死机的问题。


其实问题很简单:
调用处: llseek (int, unsigned long, unsigned long, loff_t*, int);
但是在android bionic中将其对应到函数lseek,其函数声明如下:
off_t  lseek(int, off_t, int); 这个函数只支持32位的offset偏移,应该使用如下函数:
loff_t lseek64(int, loff_t, int); 这个函数支持64位的offset偏移


下面我们来简要介绍一下bionic的主要特性:
Bionic是Android的C/C++ library, libc是GNU/Linux以及其他类Unix系统的基础函数库,
最常用的就是GNU的libc,也叫glibc。Android之所以采用bionic而不是glibc,有几个原因:


1、版权问题,因为glibc是LGPL
2、库的体积和速度,bionic要比glibc小很多。
3、提供了一些Android特定的函数,getprop LOGI等


还有些也常用uclibc,这些库未使用的原因基本相似。


懒的写,从网上搜到的的贴一下bionic主要目录结构及主要功能:
|-- Android.mk

|-- CleanSpec.mk
|-- libc   (c 库)
|   |-- Android.mk
|   |-- arch-arm  (arm构架相关的实现,主要是针对arm的优化,以及和处理器相关的调用)
|   |-- arch-sh   (ST公司的SH4体系实现)
|   |-- arch-x86  (x86架构相关的实现)
|   |-- arch-mips (mips架构相关的实现)
|   |-- bionic
|   |-- CAVEATS
|   |-- docs
|   |-- include
|   |-- inet
|   |-- Jamfile
|   |-- kernel
|   |-- MODULE_LICENSE_BSD
|   |-- netbsd
|   |-- NOTICE
|   |-- private
|   |-- README
|   |-- regex
|   |-- stdio
|   |-- stdlib
|   |-- string
|   |-- SYSCALLS.TXT
|   |-- tools
|   |-- tzcode
|   |-- unistd
|   |-- wchar
|   `-- zoneinfo
|-- libdl       (动态链接库访问接口 dlopen dlsym dlerror dlclose dladdr的实现)
|   |-- Android.mk
|   |-- arch-sh
|   |-- dltest.c
|   |-- libdl.c
|   |-- MODULE_LICENSE_BSD
|   `-- NOTICE
|-- libm   (C数学函数库, 提供了常见的数序函数和浮点运算)
|   |-- alpha
|   |-- amd64
|   |-- Android.mk
|   |-- arm
|   |-- bsdsrc
|   |-- fpclassify.c
|   |-- i386
|   |-- i387
|   |-- ia64
|   |-- include
|   |-- isinf.c
|   |-- Makefile-orig
|   |-- man
|   |-- MODULE_LICENSE_BSD_LIKE
|   |-- NOTICE
|   |-- powerpc
|   |-- sh
|   |-- sincos.c
|   |-- sparc64
|   `-- src
|-- libstdc++  (standard c++ lib)
|   |-- Android.mk
|   |-- include
|   |-- MODULE_LICENSE_BSD
|   |-- NOTICE
|   `-- src
|-- libthread_db (线程调试库,可以利用此库对多线程程序进行调试)
|   |-- Android.mk
|   |-- include
|   |-- libthread_db.c
|   |-- MODULE_LICENSE_BSD
|   `-- NOTICE
|-- linker (Android dynamic linker)
|   |-- Android.mk
|   |-- arch
|   |-- ba.c
|   |-- ba.h
|   |-- debugger.c
|   |-- dlfcn.c
|   |-- linker.c
|   |-- linker_debug.h
|   |-- linker_format.c
|   |-- linker_format.h
|   |-- linker.h
|   |-- MODULE_LICENSE_APACHE2
|   |-- NOTICE
|   |-- README.TXT
|   `-- rt.c
|-- MAINTAINERS


下面就几个重要的观点说明一下:


Core Philosophy:


  The core idea behind Bionic's design is: KEEP IT REALLY SIMPLE.


  This implies that the C library should only provide lightweight wrappers
  around kernel facilities and not try to be too smart to deal with edge cases.


  The name "Bionic" comes from the fact that it is part-BSD and part-Linux:
  its source code consists in a mix of BSD C library pieces with custom
  Linux-specific bits used to deal with threads, processes, signals and a few
  others things.


  All original BSD pieces carry the BSD copyright disclaimer. Bionic-specific 
  bits carry the Android Open Source Project copyright disclaimer. And
  everything is released under the BSD license.
  
这些在overview.txt中说明的,不翻译了,英文简洁明了更好


1、系统调用sys_call问题
Syscall stubs:


  Each system call function is implemented by a tiny assembler source fragment
  (called a "syscall stub"), which is generated automatically by
  tools/gensyscalls.py which reads the SYSCALLS.TXT file for input.


基本上的系统调用函数上层进行简单的封装,然后利用汇编代码进行具体实现将利用int 80系统中断调
用到kernel内核中的函数,包含process management,file,signals,sockets,epoll等


举例说明下:
如下面的函数提供给外部使用即lseek64函数,进行简单的封装
loff_t lseek64(int fd, loff_t off, int whence)
{
   loff_t  result;

   if ( __llseek(fd, (unsigned long)(off >> 32),(unsigned long)(off), &result, whence ) < 0 )
       return -1;

   return result;
}

自动生成的汇编代码,主要调用__NR__xxx函数,进行内核中
/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>

   .text
   .type __llseek, #function
   .globl __llseek
   .align 4
   .fnstart

__llseek:
   mov     ip, sp
   .save   {r4, r5, r6, r7}
   stmfd   sp!, {r4, r5, r6, r7}
   ldmfd   ip, {r4, r5, r6}
   ldr     r7, =__NR__llseek
   swi     #0
   ldmfd   sp!, {r4, r5, r6, r7}
   movs    r0, r0
   bxpl    lr
   b       __set_syscall_errno
   .fnend


这些代码都在bionic\libc\arch-$ARCh\syscalls下面


2、线程操作函数问题
   Bionic's C library comes with its own pthread implementation bundled in.
   This is different from other historical C libraries which:


    - place it in an external library (-lpthread)
    - play linker tricks with weak symbols at dynamic link time
    
    有如下的几个函数不支持:
    pthread_cancel()
    pthread_once()    

3、linux标准头文件问题 
Linux kernel headers:


  Bionic comes with its own set of "clean" Linux kernel headers to allow
  user-space code to use kernel-specific declarations (e.g. IOCTLs, structure
  declarations, constants, etc...). They are located in:


     ./kernel/common,
     ./kernel/arch-$ARCH


  These headers have been generated by a tool (kernel/tools/update-all.py) to
  only include the public definitions from the original Linux kernel headers.


4、外部引用bionic头文件
Include Paths:


  The Android build system should automatically provide the necessary include
  paths required to build against the C library headers. However, if you want
  to do that yourself, you will need to add:


      libc/arch-$ARCH/include
      libc/include
      libc/kernel/common
      libc/kernel/arch-$ARCH


  to your C include path.


这些就是android系统中使用的标C头文件所在处,请关注之


在这里面很多脚本使用python编写的,没有细读过.

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值