[LV] [PATCH] VAX/ELF: PLT disassembly support

Maciej W. Rozycki macro at linux-mips.org
Fri Jun 5 02:15:52 CEST 2009


Hello,

 The VAX/ELF backend lacks a platform-specific PLT disassembly helper.  
The result is the table is messed up in the dump.  Here's an example:

$ vax-linux-objdump -d -j .plt ld.so.1

ld.so.1:     file format elf32-vax


Disassembly of section .plt:

000005c8 <.plt>:
 5c8:	dd ef 7e 42 	pushl 1484c <_GLOBAL_OFFSET_TABLE_+0x4>
 5cc:	01 00 
 5ce:	17 ff 7c 42 	jmp *14850 <_GLOBAL_OFFSET_TABLE_+0x8>
 5d2:	01 00 
 5d4:	fc          	xfc
 5d5:	0f 16 ef ec 	remque $0x16,5c8 <GLIBC_2.0+0x5c8>
 5d9:	ff ff ff 
 5dc:	00          	halt
 5dd:	00          	halt
 5de:	00          	halt
 5df:	00          	halt
 5e0:	fc          	xfc
 5e1:	0f 16 ef e0 	remque $0x16,5c8 <GLIBC_2.0+0x5c8>
 5e5:	ff ff ff 
 5e8:	0c 00 00 00 	prober $0x0,$0x0,$0x0
 5ec:	fc          	xfc
 5ed:	0f 16 ef d4 	remque $0x16,5c8 <GLIBC_2.0+0x5c8>
 5f1:	ff ff ff 
 5f4:	18 00       	bgeq 5f6 <GLIBC_2.0+0x5f6>
 5f6:	00          	halt
 5f7:	00          	halt
 5f8:	fc          	xfc
 5f9:	0f 16 ef c8 	remque $0x16,5c8 <GLIBC_2.0+0x5c8>
 5fd:	ff ff ff 
 600:	24 00 00 00 	cvtpt $0x0,$0x0,$0x0,*0xbcef160f(ap),*31060d <_end+0x2fb511>
 604:	fc 0f 16 ef 
 608:	bc ff ff ff 
 60c:	30 00 
	...

The patch below implements the helper needed.  There is a small issue with 
weak symbols which do not have the BSF_FUNCTION flag set and therefore do 
not match the usual logic to trigger entry mask decoding.  To solve this 
problem, I have made use of an observation that the BSF_SYNTHETIC flag is 
only set for PLT symbols for the VAX target.  If this ever changes in the 
future code will have to be adjusted accordingly.

 Here's a dump of the same PLT as above obtained with the patch applied:

$ vax-linux-objdump -d -j .plt ld.so.1

ld.so.1:     file format elf32-vax


Disassembly of section .plt:

000005c8 <__libc_memalign at plt-0xc>:
 5c8:	dd ef 7e 42 	pushl 1484c <_GLOBAL_OFFSET_TABLE_+0x4>
 5cc:	01 00 
 5ce:	17 ff 7c 42 	jmp *14850 <_GLOBAL_OFFSET_TABLE_+0x8>
 5d2:	01 00 

000005d4 <__libc_memalign at plt>:
 5d4:	fc 0f       	.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
 5d6:	16 ef ec ff 	jsb 5c8 <GLIBC_2.0+0x5c8>
 5da:	ff ff 
 5dc:	00 00 00 00 	.long 0x00000000

000005e0 <malloc at plt>:
 5e0:	fc 0f       	.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
 5e2:	16 ef e0 ff 	jsb 5c8 <GLIBC_2.0+0x5c8>
 5e6:	ff ff 
 5e8:	0c 00 00 00 	.long 0x0000000c

000005ec <calloc at plt>:
 5ec:	fc 0f       	.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
 5ee:	16 ef d4 ff 	jsb 5c8 <GLIBC_2.0+0x5c8>
 5f2:	ff ff 
 5f4:	18 00 00 00 	.long 0x00000018

000005f8 <realloc at plt>:
 5f8:	fc 0f       	.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
 5fa:	16 ef c8 ff 	jsb 5c8 <GLIBC_2.0+0x5c8>
 5fe:	ff ff 
 600:	24 00 00 00 	.long 0x00000024

00000604 <free at plt>:
 604:	fc 0f       	.word 0x0ffc # Entry mask: < r11 r10 r9 r8 r7 r6 r5 r4 r3 r2 >
 606:	16 ef bc ff 	jsb 5c8 <GLIBC_2.0+0x5c8>
 60a:	ff ff 
 60c:	30 00 00 00 	.long 0x00000030

bfd/
2009-06-04  Maciej W. Rozycki  <macro at linux-mips.org>

	* elf32-vax.c (elf_vax_plt_sym_val): New function.
	(elf_backend_plt_sym_val): Define.

opcodes/
2009-06-04  Maciej W. Rozycki  <macro at linux-mips.org>

	* vax-dis.c (is_function_entry): Return success for synthetic 
	symbols too.
	(is_plt_tail): New function.
	(print_insn_vax): Decode PLT entry offset longword.

 OK to apply?

  Maciej

binutils-2.19.1-vax-plt-sym.patch
diff -up --recursive --new-file binutils-2.19.1.macro/bfd/elf32-vax.c binutils-2.19.1/bfd/elf32-vax.c
--- binutils-2.19.1.macro/bfd/elf32-vax.c	2008-01-11 09:07:03.000000000 +0000
+++ binutils-2.19.1/bfd/elf32-vax.c	2009-05-15 22:46:54.000000000 +0000
@@ -47,6 +47,8 @@ static bfd_boolean elf_vax_finish_dynami
 						  Elf_Internal_Sym *);
 static bfd_boolean elf_vax_finish_dynamic_sections (bfd *,
 						    struct bfd_link_info *);
+static bfd_vma elf_vax_plt_sym_val (bfd_vma, const asection *,
+				    const arelent *);
 
 static bfd_boolean elf32_vax_set_private_flags (bfd *, flagword);
 static bfd_boolean elf32_vax_merge_private_bfd_data (bfd *, bfd *);
@@ -2068,6 +2070,13 @@ elf_vax_finish_dynamic_sections (bfd *ou
   return TRUE;
 }
 
+static bfd_vma
+elf_vax_plt_sym_val (bfd_vma i, const asection *plt,
+		     const arelent *rel ATTRIBUTE_UNUSED)
+{
+  return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
 #define TARGET_LITTLE_SYM		bfd_elf32_vax_vec
 #define TARGET_LITTLE_NAME		"elf32-vax"
 #define ELF_MACHINE_CODE		EM_VAX
@@ -2092,6 +2101,7 @@ elf_vax_finish_dynamic_sections (bfd *ou
 					elf_vax_finish_dynamic_sections
 #define elf_backend_gc_mark_hook	elf_vax_gc_mark_hook
 #define elf_backend_gc_sweep_hook	elf_vax_gc_sweep_hook
+#define elf_backend_plt_sym_val		elf_vax_plt_sym_val
 #define bfd_elf32_bfd_merge_private_bfd_data \
                                         elf32_vax_merge_private_bfd_data
 #define bfd_elf32_bfd_set_private_flags \
diff -up --recursive --new-file binutils-2.19.1.macro/opcodes/vax-dis.c binutils-2.19.1/opcodes/vax-dis.c
--- binutils-2.19.1.macro/opcodes/vax-dis.c	2007-07-05 09:49:02.000000000 +0000
+++ binutils-2.19.1/opcodes/vax-dis.c	2009-05-15 23:52:10.000000000 +0000
@@ -171,21 +171,24 @@ free_entry_array (void)
     }
 }
 #endif
-/* Check if the given address is a known function entry. Either there must
-   be a symbol of function type at this address, or the address must be
-   a forced entry point.  The later helps in disassembling ROM images, because
-   there's no symbol table at all.  Forced entry points can be given by
-   supplying several -M options to objdump: -M entry:0xffbb7730.  */
+/* Check if the given address is a known function entry point.  This is
+   the case if there is a symbol of the function type at this address.
+   We also check for synthetic symbols as these are used for PLT entries
+   (weak undefined symbols may not have the function type set).  Finally
+   the address may have been forced to be treated as an entry point.  The
+   latter helps in disassembling ROM images, because there's no symbol
+   table at all.  Forced entry points can be given by supplying several
+   -M options to objdump: -M entry:0xffbb7730.  */
 
 static bfd_boolean
 is_function_entry (struct disassemble_info *info, bfd_vma addr)
 {
   unsigned int i;
 
-  /* Check if there's a BSF_FUNCTION symbol at our address.  */
+  /* Check if there's a function or PLT symbol at our address.  */
   if (info->symbols
       && info->symbols[0]
-      && (info->symbols[0]->flags & BSF_FUNCTION)
+      && (info->symbols[0]->flags & (BSF_FUNCTION | BSF_SYNTHETIC))
       && addr == bfd_asymbol_value (info->symbols[0]))
     return TRUE;
 
@@ -197,6 +200,22 @@ is_function_entry (struct disassemble_in
   return FALSE;
 }
 
+/* Check if the given address is the last longword of a PLT entry.
+   This longword is data and depending on the value it may interfere
+   with disassembly of further PLT entries.  We make use of the fact
+   PLT symbols are marked BSF_SYNTHETIC.  */
+static bfd_boolean
+is_plt_tail (struct disassemble_info *info, bfd_vma addr)
+{
+  if (info->symbols
+      && info->symbols[0]
+      && (info->symbols[0]->flags & BSF_SYNTHETIC)
+      && addr == bfd_asymbol_value (info->symbols[0]) + 8)
+    return TRUE;
+
+  return FALSE;
+}
+
 static int
 print_insn_mode (const char *d,
 		 int size,
@@ -412,6 +431,18 @@ print_insn_vax (bfd_vma memaddr, disasse
       return 2;
     }
 
+  /* Decode PLT entry offset longword.  */
+  if (is_plt_tail (info, memaddr))
+    {
+      int offset;
+
+      FETCH_DATA (info, buffer + 4);
+      offset = buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
+      (*info->fprintf_func) (info->stream, ".long 0x%08x", offset);
+
+      return 4;
+    }
+
   for (votp = &votstrs[0]; votp->name[0]; votp++)
     {
       vax_opcodeT opcode = votp->detail.code;


_______________________________________________
Linux-Vax mailing list
Linux-Vax at mail.pergamentum.com
http://mail.pergamentum.com/mailman/listinfo/linux-vax




More information about the Vax-linux mailing list