This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: [PATCH] Explicitly get .dynamic section for "readelf -d"
- From: Jie Zhang <zhangjie at magima dot com dot cn>
- To: Nick Clifton <nickc at redhat dot com>
- Cc: binutils at sources dot redhat dot com
- Date: Mon, 14 Jun 2004 16:42:31 +0800
- Subject: Re: [PATCH] Explicitly get .dynamic section for "readelf -d"
- References: <40BDA689.7000303@magima.com.cn> <40C89C45.1020905@redhat.com>
Nick Clifton wrote:
There is a small problem with it - it contains duplicated code. I think
that a better approach would be to put the scan for the .dynamic section
into the code in process_program_headers() where dynamic_addr and
dynamic_size are currently initialised. Could you try this out please ?
Here is it. But I'm afraid it is not good enough yet.
The -d option of readelf is for displaying the contents of the file's
dynamic section as stated in the document. However, almost all relevant
code say dynamic *segment* rather than dynamic *section*. For most
targets dynamic segment contains only .dynamic section and they are
equivalent, but for SGI's MIPS this is not true. Is it worth changing
all "dynamic segment" to "dynamic section", e.g. process_dynamic_segment
to process_dynamic_section and dynamic_segment to dynamic_section?
The .dynamic section, I think now, should be the first section in the
dynamic segment. Since section header table is optional in executable
file, we cannot always rely on it to relocate .dynamic section. If a
script does not make it come first in the segment, it's the script's
fault not others. So I think that it would better to make ld warn (or
error) if the .dynamic section is not the first section in the dynamic
segment. Is this reasonable? Is there any target other than MIPS that
has more than one section in dynamic segment? If it is the only target,
I'm going to add check in _bfd_mips_elf_modify_segment_map ().
Otherwise, I'm going to add check in map_sections_to_segments (). Are
they the right places?
--
Jie
2004-06-14 Jie Zhang <zhangjie@magima.com.cn>
* binutils/readelf.c (process_program_headers): Better locate .dynamic section.
--- binutils-040601.old/binutils/readelf.c 2004-05-29 08:12:03.000000000 +0800
+++ binutils-040601/binutils/readelf.c 2004-06-14 15:09:01.000000000 +0800
@@ -3147,8 +3147,41 @@ process_program_headers (FILE *file)
if (dynamic_addr)
error (_("more than one dynamic segment\n"));
- dynamic_addr = segment->p_offset;
- dynamic_size = segment->p_filesz;
+ /* Try to locate the .dynamic section. If there is section header
+ table, we can easily locate it. */
+ if (section_headers != NULL)
+ {
+ Elf_Internal_Shdr *sec;
+ unsigned int j;
+
+ for (j = 0, sec = section_headers;
+ j < elf_header.e_shnum;
+ j++, sec++)
+ if (strcmp (SECTION_NAME (sec), ".dynamic") == 0)
+ break;
+
+ if (j == elf_header.e_shnum || sec->sh_size == 0)
+ {
+ error (_("no .dynamic section in the dynamic segment"));
+ break;
+ }
+
+ dynamic_addr = sec->sh_offset;
+ dynamic_size = sec->sh_size;
+
+ if (dynamic_addr < segment->p_offset
+ || dynamic_addr > segment->p_offset + segment->p_filesz)
+ warn (_("the .dynamic section is not in the dynamic segment"));
+ else if (dynamic_addr > segment->p_offset)
+ warn (_("the .dynamic section is not the first section in the dynamic segment."));
+ }
+ /* Otherwise, we can only assume that the .dynamic section is the
+ first section in the DYNAMIC segment. */
+ else
+ {
+ dynamic_addr = segment->p_offset;
+ dynamic_size = segment->p_filesz;
+ }
break;
case PT_INTERP: