程序集弱符号未按(I)预期工作



我正在与riscv-corev32-elf-gcc进行交叉编译。

在第一个文件"generic.S"中我有以下代码:

.section .text.handlers
.weak u_sw_irq_handler
.weak __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler 
jal x0, __no_irq_handler     
jal x0, __no_irq_handler
...

.section .text
reset_handler:
la t0, vector_table
csrw mtvec, t0

在第二个文件"custom.S"中我有以下代码:

.section .text.handlers
.<x> u_sw_irq_handler
.<x> __no_irq_handler
.section .vectors, "ax"
vector_table:
jal x0, u_sw_irq_handler 
jal x0, ISR_1_handler     
jal x0, ISR_2_handler
...

其中<x>globallocal

global时,这是反汇编的(部分(结果:

00001000 <vector_table>:
1000:   7760d06f            j   e776 <u_sw_irq_handler>
1004:   1880706f            j   81cc <ISR_1_handler>
1008:   1e40706f            j   822c <ISR_2_handler>
...
1084:   7760d06f            j   e776 <u_sw_irq_handler>
1088:   7320d06f            j   e736 <__no_irq_handler>
108c:   72e0d06f            j   e736 <__no_irq_handler>
...

00001108 <reset_handler>:
1108:   00000297            auipc   t0,0x0
110c:   f7c28293            addi    t0,t0,-264 # 1000 <vector_table>
1110:   30529073            csrw    mtvec,t0

local时,这是反汇编的(部分(结果:

00001000 <vector_table>:
1000:   7760d06f            j   e776 <u_sw_irq_handler>
1004:   1880706f            j   81cc <ISR_1_handler>
1008:   1e40706f            j   822c <ISR_2_handler>
...
00001084 <vector_table>:
1084:   7760d06f            j   e776 <u_sw_irq_handler>
1088:   7320d06f            j   e736 <__no_irq_handler>
108c:   72e0d06f            j   e736 <__no_irq_handler>
...

00001108 <reset_handler>:
1108:   00000297            auipc   t0,0x0
110c:   f7c28293            addi    t0,t0,-132 # 1084 <vector_table>
1110:   30529073            csrw    mtvec,t0

但这不是我想要的:

  • 如果没有向量表的其他定义,我希望采用通用定义

  • 我希望通用定义被自定义覆盖。S定义(如果存在(,以及泛型中的reset_handler。S加载矢量表的自定义地址

  • 使用"全局"更接近我想要的,但vector_table在最后一个向量之后继续jal x0, ...

  • 使用local,reset_handler中调用的vectortable将是泛型的,而不是自定义的。

edit:很抱歉,我错过了重置处理程序反汇编的匹配日志

程序集weak符号未按预期工作

weak的工作方式与您想象的不同:

如果符号不存在于另一个对象文件中,则weak使符号成为全局符号;如果符号存在于其他对象文件中则使符号本身(!(消失。

示例(很抱歉,我的示例是x86,因为我不知道riscv32(:

.weak some_irq_handler
.weak some_other_irq_handler
vector_table:
jmp some_irq_handler
jmp some_other_irq_handler
some_irq_handler:
iret
some_other_irq_handler:
iret

如果没有其他对象文件包含.global some_irq_handler.global some_other_irq_handler,则.weak行几乎与.global行具有相同的效果。

然而,如果另一个对象文件包含这两个符号,上面的例子或多或少等于:

vector_table:
# This symbol is defined in another object file
jmp some_irq_handler
# This symbol is defined in another object file
jmp some_other_irq_handler
# The code of "some_irq_handler" is still
# present; only the label "some_irq_handler:"
# has been removed by the linker!
iret
iret
# -- Another object file --
some_irq_handler:
...

我希望通用定义被自定义覆盖。S定义如果存在。。。

情况1vector_table需要而不是位于内存中的某个地址:

在这种情况下,您可以通过以下方式进行:

.weak vector_table
vector_table:
jmp no_interrupt
jmp no_interrupt
...

如果您的项目中存在另一个矢量表,则生成的代码(链接后(将如下所示:

# -- "weak" object file --
# vector_table: - Label removed by the linker
# but the table itself is still there
jmp no_interrupt
jmp no_interrupt
...
# -- "overwriting" object file --
vector_table:
jmp interrupt1
jmp interrupt2
...

情况2vector_table需要位于内存中的某个地址:

在这种情况下,您可以通过以下方式进行操作:

.weak interrupt1
.weak interrupt2
...
vector_table:
jmp interrupt1
jmp interrupt2
...
__no_irq_handler:
interrupt1:
interrupt2:
...
interrupt256:
iret

您永远不会覆盖";通用的";中断矢量表被另一个中断矢量表覆盖,但您只覆盖符号interrupt<n>:

.global interrupt2
interrupt2:
mov al, 0x1234
out 0xE4, ax
mov al, 0x20
out 0x20, al
iret

(这也适用于C编写的代码。由于默认情况下C编译器生成函数.global而不是.weak,因此C编写的函数会覆盖.weak。(

生成的代码将如下所示:

# -- "weak" object file --
vector_table:
jmp interrupt1
jmp interrupt2
...
__no_irq_handler:
interrupt1:
# interrupt2: - Label removed by the linker
interrupt3:
...
interrupt256:
iret
# -- "overwriting" object file --
interrupt2:
mov al, 0x1234
out 0xE4, ax
mov al, 0x20
out 0x20, al
iret

相关内容

  • 没有找到相关文章

最新更新