免费注册 查看新帖 |

Chinaunix

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

请教:strip是怎么工作的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-08-03 10:20 |只看该作者 |倒序浏览
这两天碰到一个问题,在用strip来删除符号的时候,文件中的program header的虚拟地址被改动了,而起strip也报告如下错误:


BFD: stDYGBBi: section cpu1_percpu_data lma 0x300000 overlaps previous sections

那位大侠知道,给讲一下,谢谢。

strip应该只删除某些符号section吧,program header又不是多余符号,为什么要修改呢?

论坛徽章:
0
2 [报告]
发表于 2009-08-03 10:24 |只看该作者
补充一下:刚才那个报告的错误应该是一些section的位置不对,如下,section cpu[1-6]_percpu_data 的起始位置和大小都一样,好像不正常。

  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0c010000 010000 0f0000 00  AX  0   0 65536
  [ 2] .data             PROGBITS        00200000 100000 100000 00  WA  0   0 16
  [ 3] cpu0_percpu_data  PROGBITS        00300000 200000 010000 00  WA  0   0  4
  [ 4] cpu1_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1
  [ 5] cpu2_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1
  [ 6] cpu3_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1
  [ 7] cpu4_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1
  [ 8] cpu5_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1
  [ 9] cpu6_percpu_data  NOBITS          00300000 210000 010000 00  WA  0   0  1

但是这也不应该影响到修改program header吧

论坛徽章:
0
3 [报告]
发表于 2009-08-03 22:27 |只看该作者
是不是与你的编译参数有关系?
strip应该没什么错误阿

论坛徽章:
0
4 [报告]
发表于 2009-08-04 10:18 |只看该作者
我运行strip的时候没有加任何参数。

不管怎样,strip都不应该修改program header吧,现在的结果是

strip之前
  <unknown>: 8   0x000000 0x2c000000 0x2c000000 0x00000 0x4000000 RW  0x8

strip之后
  <unknown>: 8   0x000000 0x37f00000 0x2c000000 0x00000 0x4000000 RW  0x8


奇怪吧?

论坛徽章:
0
5 [报告]
发表于 2009-08-04 17:03 |只看该作者
跟踪了一下strip,发现确实修改了vaddr,但是不知道所以然,谁能解释一下最后一段?

static bfd_boolean
copy_elf_program_header (bfd *ibfd, bfd *obfd)
{
  Elf_Internal_Ehdr *iehdr;
  struct elf_segment_map *map;
  struct elf_segment_map *map_first;
  struct elf_segment_map **pointer_to_map;
  Elf_Internal_Phdr *segment;
  unsigned int i;
  unsigned int num_segments;
  bfd_boolean phdr_included = FALSE;
  bfd_boolean p_paddr_valid;

  iehdr = elf_elfheader (ibfd);

  map_first = NULL;
  pointer_to_map = &map_first;

  /* If all the segment p_paddr fields are zero, don't set
     map->p_paddr_valid.  */

  p_paddr_valid = FALSE;
  num_segments = elf_elfheader (ibfd)->e_phnum;
  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    if (segment->p_paddr != 0)
      {
    p_paddr_valid = TRUE;
    break;
      }

  for (i = 0, segment = elf_tdata (ibfd)->phdr;
       i < num_segments;
       i++, segment++)
    {
      asection *section;
      unsigned int section_count;
      bfd_size_type amt;
      Elf_Internal_Shdr *this_hdr;
      asection *first_section = NULL;
      asection *lowest_section = NULL;

      /* Compute how many sections are in this segment.  */
      for (section = ibfd->sections, section_count = 0;
       section != NULL;
       section = section->next)
    {
      this_hdr = &(elf_section_data(section)->this_hdr);
      if (ELF_IS_SECTION_IN_SEGMENT_FILE (this_hdr, segment))
        {
          if (!first_section)
        first_section = lowest_section = section;
          if (section->lma < lowest_section->lma)
        lowest_section = section;
          section_count++;
        }
    }

      /* Allocate a segment map big enough to contain
     all of the sections we have selected.  */

      amt = sizeof (struct elf_segment_map);
      if (section_count != 0)
    amt += ((bfd_size_type) section_count - 1) * sizeof (asection *);
      map = bfd_zalloc (obfd, amt);
      if (map == NULL)
    return FALSE;

      /* Initialize the fields of the output segment map with the
     input segment.  */

      map->next = NULL;
      map->p_type = segment->p_type;
      map->p_flags = segment->p_flags;
      map->p_flags_valid = 1;
      map->p_paddr = segment->p_paddr;
      map->p_paddr_valid = p_paddr_valid;
      map->p_align = segment->p_align;
      map->p_align_valid = 1;
      map->p_vaddr_offset = 0;

      if (map->p_type == PT_GNU_RELRO)
    {
      /* The PT_GNU_RELRO segment may contain the first a few
         bytes in the .got.plt section even if the whole .got.plt
         section isn't in the PT_GNU_RELRO segment.  We won't
         change the size of the PT_GNU_RELRO segment.  */

      map->p_size = segment->p_memsz;
      map->p_size_valid = 1;
    }

      /* Determine if this segment contains the ELF file header
     and if it contains the program headers themselves.  */

      map->includes_filehdr = (segment->p_offset == 0
                   && segment->p_filesz >= iehdr->e_ehsize);

      map->includes_phdrs = 0;
      if (! phdr_included || segment->p_type != PT_LOAD)
    {
      map->includes_phdrs =
        (segment->p_offset <= (bfd_vma) iehdr->e_phoff
         && (segment->p_offset + segment->p_filesz
         >= ((bfd_vma) iehdr->e_phoff
             + iehdr->e_phnum * iehdr->e_phentsize)));

      if (segment->p_type == PT_LOAD && map->includes_phdrs)
        phdr_included = TRUE;
    }

      if (map->includes_filehdr && first_section)
    /* We need to keep the space used by the headers fixed.  */
    map->header_size = first_section->vma - segment->p_vaddr;
      
      if (!map->includes_phdrs
      && !map->includes_filehdr
      && map->p_paddr_valid)
    /* There is some other padding before the first section.  */
    map->p_vaddr_offset = ((lowest_section ? lowest_section->lma : 0)
                   - segment->p_paddr);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP