harry_he 发表于 2009-08-03 10:20

请教:strip是怎么工作的?

这两天碰到一个问题,在用strip来删除符号的时候,文件中的program header的虚拟地址被改动了,而起strip也报告如下错误:


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

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

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

harry_he 发表于 2009-08-03 10:24

补充一下:刚才那个报告的错误应该是一些section的位置不对,如下,section cpu_percpu_data 的起始位置和大小都一样,好像不正常。

Name            Type            Addr   Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   00
[ 1] .text             PROGBITS      0c010000 010000 0f0000 00AX0   0 65536
[ 2] .data             PROGBITS      00200000 100000 100000 00WA0   0 16
[ 3] cpu0_percpu_dataPROGBITS      00300000 200000 010000 00WA0   04
[ 4] cpu1_percpu_dataNOBITS          00300000 210000 010000 00WA0   01
[ 5] cpu2_percpu_dataNOBITS          00300000 210000 010000 00WA0   01
[ 6] cpu3_percpu_dataNOBITS          00300000 210000 010000 00WA0   01
[ 7] cpu4_percpu_dataNOBITS          00300000 210000 010000 00WA0   01
[ 8] cpu5_percpu_dataNOBITS          00300000 210000 010000 00WA0   01
[ 9] cpu6_percpu_dataNOBITS          00300000 210000 010000 00WA0   01

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

emmoblin 发表于 2009-08-03 22:27

是不是与你的编译参数有关系?
strip应该没什么错误阿

harry_he 发表于 2009-08-04 10:18

我运行strip的时候没有加任何参数。

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

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

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


奇怪吧?

harry_he 发表于 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);
页: [1]
查看完整版本: 请教:strip是怎么工作的?