美文网首页
【转】Android-- bionic介绍

【转】Android-- bionic介绍

作者: Franck2020 | 来源:发表于2020-04-14 10:45 被阅读0次

原文链接

小组人员移植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编写的,没有细读过.

————————————————

版权声明:本文为CSDN博主「andyhuabing」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/andyhuabing/article/details/7183369

相关文章

网友评论

      本文标题:【转】Android-- bionic介绍

      本文链接:https://www.haomeiwen.com/subject/ngkzmhtx.html