免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3944 | 回复: 3
打印 上一主题 下一主题

关于glibc源码,求助高手!! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-04-05 23:59 |只看该作者 |倒序浏览
由于工作需要,有时候得查看一些c库函数的实现,比如,现在要看isspace接口的实现,
在glibc的源码中找到如下:
# define isspace(c)        __isctype((c), _ISspace)

int
__isctype (ch, mask)
     int ch;
     int mask;
{
  return (((uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 12
          [(int) (ch)] & mask);
}
weak_alias (__isctype, isctype)

对于_NL_CURRENT我就无能为力了,找不着它究竟是干什么的。
然后我写了个小程序gcc预处理之后,发现isspace被预处理为:
((*__ctype_b_loc ())[(int) ((c))] & (unsigned short int) _ISspace);
我又查找__ctype_b_loc的实现,如下:

CTYPE_EXTERN_INLINE const uint16_t ** __attribute__ ((const))
__ctype_b_loc (void)
{
  const uint16_t **tablep = __libc_tsd_address (const uint16_t *, CTYPE_B);
  if (__builtin_expect (*tablep == NULL, 0))
    *tablep = (const uint16_t *) _NL_CURRENT (LC_CTYPE, _NL_CTYPE_CLASS) + 128;
  return tablep;
}

#define __libc_tsd_address(TYPE, KEY) \
  ((TYPE *) __hurd_threadvar_location (_HURD_THREADVAR_##KEY))

_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
__hurd_threadvar_location (enum __hurd_threadvar_index __index)
{
  return __hurd_threadvar_location_from_sp (__index,
                                            __thread_stack_pointer ());
}

_HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
__hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index,
                                   void *__sp)
{
  unsigned long int __stack = (unsigned long int) __sp;
  return &((__stack >= __hurd_sigthread_stack_base &&
            __stack < __hurd_sigthread_stack_end)
           ? __hurd_sigthread_variables
           : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) +
                                    __hurd_threadvar_stack_offset))[__index];
}

看到这里我又没有头绪了,都搞成什么stack pointer处理了,有没有什么材料能推荐一下的,这西都在干什么?

论坛徽章:
0
2 [报告]
发表于 2012-04-06 00:18 |只看该作者
上一层还没弄清楚就进入细节,当然会越来越糊涂。而且不知道你看的是哪个版本。
  1. enum
  2. {
  3.   _ISupper = _ISbit (0),        /* UPPERCASE.  */
  4.   _ISlower = _ISbit (1),        /* lowercase.  */
  5.   _ISalpha = _ISbit (2),        /* Alphabetic.  */
  6.   _ISdigit = _ISbit (3),        /* Numeric.  */
  7.   _ISxdigit = _ISbit (4),        /* Hexadecimal numeric.  */
  8.   _ISspace = _ISbit (5),        /* Whitespace.  */
  9.   _ISprint = _ISbit (6),        /* Printing.  */
  10.   _ISgraph = _ISbit (7),        /* Graphical.  */
  11.   _ISblank = _ISbit (8),        /* Blank (usually SPC and TAB).  */
  12.   _IScntrl = _ISbit (9),        /* Control character.  */
  13.   _ISpunct = _ISbit (10),        /* Punctuation.  */
  14.   _ISalnum = _ISbit (11)        /* Alphanumeric.  */
  15. };
  16. #endif /* ! _ISbit  */

  17. /* These are defined in ctype-info.c.
  18.    The declarations here must match those in localeinfo.h.

  19.    In the thread-specific locale model (see `uselocale' in <locale.h>)
  20.    we cannot use global variables for these as was done in the past.
  21.    Instead, the following accessor functions return the address of
  22.    each variable, which is local to the current thread if multithreaded.

  23.    These point into arrays of 384, so they can be indexed by any `unsigned
  24.    char' value [0,255]; by EOF (-1); or by any `signed char' value
  25.    [-128,-1).  ISO C requires that the ctype functions work for `unsigned
  26.    char' values and for EOF; we also support negative `signed char' values
  27.    for broken old programs.  The case conversion arrays are of `int's
  28.    rather than `unsigned char's because tolower (EOF) must be EOF, which
  29.    doesn't fit into an `unsigned char'.  But today more important is that
  30.    the arrays are also used for multi-byte character sets.  */
  31. extern __const unsigned short int **__ctype_b_loc (void)
  32.      __attribute__ ((__const));
  33. extern __const __int32_t **__ctype_tolower_loc (void)
  34.      __attribute__ ((__const));
  35. extern __const __int32_t **__ctype_toupper_loc (void)
  36.      __attribute__ ((__const));

  37. #define __isctype(c, type) \
  38.   ((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
复制代码
__isctype 是用来判断一个字符是否属于某一类,类别是在enum里面确定好的,每类对应一个bit。方法就是在一个数组中检索这个字符的类型,然后与type做AND,检测对应的bit是否设置。

__ctype_b_loc在上面的注释里面也一清二楚,为了支持多线程云云,...,他返回了一个384个字节的数组(128+256=384),指针指向第128个字节的位置,这样的话,就算你传递一个负的signed char [-128, -1],也不会出错。

论坛徽章:
0
3 [报告]
发表于 2012-04-06 21:21 |只看该作者
多谢,能给推荐一些学习材料吗?回复 2# sonicling


   

论坛徽章:
0
4 [报告]
发表于 2012-04-06 22:10 |只看该作者
回复 3# thelordsaves


    没。
1. 多做点项目
2. 多看别人的项目

就这两条,没有捷径。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP