This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Does your .eh_frame_hdr change work with DW_EH_PE_absptr?
On Thu, Feb 14, 2002 at 09:36:28PM +0100, Jakub Jelinek wrote:
> On Thu, Feb 14, 2002 at 12:20:12PM -0800, H . J . Lu wrote:
> > I don't know what the best way to fix it is. Given the problem I see
> > on Linux/mips, I don't know how well your scheme will work on other
> > platforms. The key is you have to make sure the .eh_frame_hdr section
> > needs no run-time relocation or provide the relocation records for it.
> > I believe you should require the .eh_frame_hdr section needs no
> > run-time relocation.
>
> .eh_frame_hdr never needs any run-time relocation.
> It always uses pcrel encoding.
>
Here is the problem:
#ifndef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) DW_EH_PE_absptr
#endif
It is true that .eh_frame_hdr itself doesn't need run-time relocation.
But the VALUEs stored in .eh_frame_hdr may be the one before run-time
relocation. It is the case for Linux/mips, which uses DW_EH_PE_absptr.
You have to make sure the VALUEs stored in .eh_frame_hdr need no
run-time relocations. But there are no checks in elf-eh-frame.c for
run-time relocations on .eh_frame_hdr. As the result, ld generates the
wrong binary silently. I am enclosing a simple asm code. The initial
loc field in FDE is
$LFB1:
...
.4byte $LFB1
It needs the run-time relocation. But the value stored in .eh_frame_hdr
is before the run-time relocation is made.
BTW, this gcc patch seems to pass my very limited test.
H.J.
---
2002-02-14 H.J. Lu <hjl@gnu.org>
* config/mips/linux.h (ASM_PREFERRED_EH_DATA_FORMAT): New.
--- gcc/config/mips/linux.h.eh Fri Feb 8 17:33:04 2002
+++ gcc/config/mips/linux.h Thu Feb 14 12:25:22 2002
@@ -283,6 +283,9 @@ void FN () \
pseudo-ops. */
#define FUNCTION_NAME_ALREADY_DECLARED
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
+ (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4)
+
/* The glibc _mcount stub will save $v0 for us. Don't mess with saving
it, since ASM_OUTPUT_REG_PUSH/ASM_OUTPUT_REG_POP do not work in the
presence of $gp-relative calls. */
---
.file 1 "foo.cc"
.section .mdebug.abi32
.previous
.abicalls
.globl _Unwind_Resume
.text
.align 2
.globl main
.ent main
.type main,@function
main:
$LFB1:
.frame $sp,40,$31 # vars= 0, regs= 3/0, args= 16, extra= 8
.mask 0x90010000,-8
.fmask 0x00000000,0
.set noreorder
.cpload $25
.set reorder
subu $sp,$sp,40
.cprestore 16
$LCFI0:
li $4,4 # 0x4
sw $31,32($sp)
$LCFI1:
sw $28,28($sp)
$LCFI2:
sw $16,24($sp)
$LCFI3:
la $25,__cxa_allocate_exception
jal $31,$25
li $3,99 # 0x63
sw $3,0($2)
move $4,$2
la $5,_ZTIi
move $6,$0
$LEHB0:
la $25,__cxa_throw
jal $31,$25
$LEHE0:
$L11:
lw $28,16($sp)
li $2,1 # 0x1
bne $5,$2,$L12
la $25,__cxa_begin_catch
jal $31,$25
lw $16,0($2)
la $25,__cxa_end_catch
jal $31,$25
move $2,$16
lw $31,32($sp)
lw $16,24($sp)
#nop
.set noreorder
.set nomacro
j $31
addu $sp,$sp,40
.set macro
.set reorder
$L12:
$LEHB1:
la $25,_Unwind_Resume
jal $31,$25
$LEHE1:
$LFE1:
.end main
.section .gcc_except_table,"aw",@progbits
.align 2
$LLSDA1:
.byte 0xff
.byte 0x0
.uleb128 $LLSDATT1-$LLSDATTD1
$LLSDATTD1:
.byte 0x1
.uleb128 $LLSDACSE1-$LLSDACSB1
$LLSDACSB1:
.uleb128 $LEHB0-$LFB1
.uleb128 $LEHE0-$LEHB0
.uleb128 $L11-$LFB1
.uleb128 0x1
.uleb128 $LEHB1-$LFB1
.uleb128 $LEHE1-$LEHB1
.uleb128 0x0
.uleb128 0x0
$LLSDACSE1:
.byte 0x1
.byte 0x0
.align 2
.word _ZTIi
$LLSDATT1:
.text
.section .eh_frame,"aw",@progbits
$Lframe1:
.4byte $LECIE1-$LSCIE1
$LSCIE1:
.4byte 0x0
.byte 0x1
.ascii "zPL\000"
.uleb128 0x1
.sleb128 4
.byte 0x40
.uleb128 0x6
.byte 0x0
.4byte __gxx_personality_v0
.byte 0x0
.byte 0xc
.uleb128 0x1d
.uleb128 0x0
.align 2
$LECIE1:
$LSFDE1:
.4byte $LEFDE1-$LASFDE1
$LASFDE1:
.4byte $LASFDE1-$Lframe1
.4byte $LFB1
.4byte $LFE1-$LFB1
.uleb128 0x4
.4byte $LLSDA1
.byte 0x4
.4byte $LCFI0-$LFB1
.byte 0xe
.uleb128 0x28
.byte 0x4
.4byte $LCFI3-$LCFI0
.byte 0x11
.uleb128 0x10
.sleb128 -4
.byte 0x11
.uleb128 0x1c
.sleb128 -3
.byte 0x11
.uleb128 0x40
.sleb128 -2
.align 2
$LEFDE1:
.align 0
.ident "GCC: (GNU) 3.1 20020207 (experimental)"