fix(elf): relocation records, DWARF tables and per-architecture frame data
Assisted-by: GLM 5.3
This commit is contained in:
+49
-3
@@ -13,6 +13,12 @@ import (
|
||||
const (
|
||||
emLOONGARCH = 258 // EM_LOONGARCH
|
||||
|
||||
// EF_LOONGARCH_ABI_DOUBLE_FLOAT | EF_LOONGARCH_OBJABI_V1: the flags the
|
||||
// Go toolchain writes (cmd/link/internal/ld/elf.go: Flags = 0x43 for
|
||||
// Loong64). System linkers refuse to merge ET_REL objects whose float
|
||||
// ABI differs, so 0 (soft-float) would make the object unlinkable.
|
||||
efLarchAbiDoubleObjV1 = 0x43
|
||||
|
||||
// LoongArch relocation types (the ELF psABI).
|
||||
rLarchPCALAHI20 = 71 // R_LARCH_PCALA_HI20 (pcalau12i)
|
||||
rLarchPCALALO12 = 72 // R_LARCH_PCALA_LO12 (addi.d/ld/st)
|
||||
@@ -187,9 +193,25 @@ func (img *Image) ELFLOONG64Object() ([]byte, error) {
|
||||
out = append(out, 0)
|
||||
}
|
||||
}
|
||||
dw := appendDWARFSections(&out, img, "gasm.s", symIdx, dwAlign)
|
||||
dw := appendDWARFSections(&out, img, dwarfSourceName(img), symIdx, dwAlign, cfiLOONG64)
|
||||
dwarfStart := 0 // section index of .debug_abbrev, set when DWARF is present
|
||||
if dw != nil {
|
||||
nSections += 4
|
||||
// Five DWARF sections: .debug_abbrev, .debug_info, .debug_line,
|
||||
// .debug_line_str and .debug_frame (the CIE is unconditional, so
|
||||
// the frame section is always present), plus the relocation
|
||||
// sections below when they carry entries.
|
||||
dwarfStart = nSections
|
||||
nSections += 5
|
||||
appendDWARFRelas(&out, dw, rLarchAbs64, dwAlign)
|
||||
if dw.infoRelaCount > 0 {
|
||||
nSections++
|
||||
}
|
||||
if dw.lineRelaCount > 0 {
|
||||
nSections++
|
||||
}
|
||||
if dw.frameRelaCount > 0 {
|
||||
nSections++
|
||||
}
|
||||
}
|
||||
|
||||
align(8)
|
||||
@@ -218,13 +240,37 @@ func (img *Image) ELFLOONG64Object() ([]byte, error) {
|
||||
putSh(".rela.text", shtRela, 0, relaOff, 24*len(relas), secSymtab, secText, 8, 24)
|
||||
}
|
||||
putSh(".shstrtab", shtStrtab, 0, shstrOff, len(stSections.bytes()), 0, 0, 1, 0)
|
||||
// DWARF section headers; their indices follow the write order.
|
||||
if dw != nil {
|
||||
// secIdx is a running section index: each putSh below emits the
|
||||
// next header, and the sh_info of a .rela section names the index
|
||||
// of the section it relocates.
|
||||
secIdx := dwarfStart
|
||||
putSh(".debug_abbrev", shtProgbits, 0, dw.abbrevOff, dw.abbrevSize, 0, 0, 1, 0)
|
||||
secIdx++
|
||||
putSh(".debug_info", shtProgbits, 0, dw.infoOff, dw.infoSize, 0, 0, 1, 0)
|
||||
secInfoIdx := secIdx
|
||||
secIdx++
|
||||
if dw.infoRelaCount > 0 {
|
||||
putSh(".rela.debug_info", shtRela, 0, dw.infoRelaOff, 24*dw.infoRelaCount, secSymtab, secInfoIdx, 8, 24)
|
||||
secIdx++
|
||||
}
|
||||
putSh(".debug_line", shtProgbits, 0, dw.lineOff, dw.lineSize, 0, 0, 1, 0)
|
||||
secLineIdx := secIdx
|
||||
secIdx++
|
||||
if dw.lineRelaCount > 0 {
|
||||
putSh(".rela.debug_line", shtRela, 0, dw.lineRelaOff, 24*dw.lineRelaCount, secSymtab, secLineIdx, 8, 24)
|
||||
secIdx++
|
||||
}
|
||||
putSh(".debug_line_str", shtProgbits, 0, dw.lineStrOff, dw.lineStrSize, 0, 0, 1, 0)
|
||||
secIdx++
|
||||
if dw.frameSize > 0 {
|
||||
putSh(".debug_frame", shtProgbits, 0, dw.frameOff, dw.frameSize, 0, 0, 8, 0)
|
||||
secFrameIdx := secIdx
|
||||
secIdx++
|
||||
if dw.frameRelaCount > 0 {
|
||||
putSh(".rela.debug_frame", shtRela, 0, dw.frameRelaOff, 24*dw.frameRelaCount, secSymtab, secFrameIdx, 8, 24)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +283,7 @@ func (img *Image) ELFLOONG64Object() ([]byte, error) {
|
||||
le.PutUint64(hdr[24:], 0)
|
||||
le.PutUint64(hdr[32:], 0)
|
||||
le.PutUint64(hdr[40:], uint64(shoff))
|
||||
le.PutUint32(hdr[48:], 0)
|
||||
le.PutUint32(hdr[48:], efLarchAbiDoubleObjV1)
|
||||
le.PutUint16(hdr[52:], 64)
|
||||
le.PutUint16(hdr[54:], 0)
|
||||
le.PutUint16(hdr[56:], 0)
|
||||
|
||||
Reference in New Issue
Block a user