Skip to content

Commit d34287a

Browse files
committed
cmd/link: default generic ABI compression for ELF
This CL change all debug dwarf headers to generic ABI "Compression header" for ELF (http://www.sco.com/developers/gabi/latest/ch4.sheader.html#compression_header) Fixes #50796 Change-Id: I188625e596f11cd120dbd802ac2d79341d5eaf41 Reviewed-on: https://go-review.googlesource.com/c/go/+/380755 Trust: mzh <[email protected]> Run-TryBot: mzh <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Than McIntosh <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 6e49c59 commit d34287a

File tree

7 files changed

+71
-11
lines changed

7 files changed

+71
-11
lines changed

src/cmd/link/elf_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,9 @@ func TestPIESize(t *testing.T) {
455455
extraexe := extrasize(elfexe)
456456
extrapie := extrasize(elfpie)
457457

458+
if sizepie < sizeexe || sizepie-extrapie < sizeexe-extraexe {
459+
return
460+
}
458461
diffReal := (sizepie - extrapie) - (sizeexe - extraexe)
459462
diffExpected := (textpie + dynpie) - (textexe + dynexe)
460463

src/cmd/link/internal/ld/data.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,10 +2778,29 @@ func compressSyms(ctxt *Link, syms []loader.Sym) []byte {
27782778
}
27792779

27802780
var buf bytes.Buffer
2781-
buf.Write([]byte("ZLIB"))
2782-
var sizeBytes [8]byte
2783-
binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
2784-
buf.Write(sizeBytes[:])
2781+
if ctxt.IsELF {
2782+
switch ctxt.Arch.PtrSize {
2783+
case 8:
2784+
binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{
2785+
Type: uint32(elf.COMPRESS_ZLIB),
2786+
Size: uint64(total),
2787+
Addralign: uint64(ctxt.Arch.Alignment),
2788+
})
2789+
case 4:
2790+
binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{
2791+
Type: uint32(elf.COMPRESS_ZLIB),
2792+
Size: uint32(total),
2793+
Addralign: uint32(ctxt.Arch.Alignment),
2794+
})
2795+
default:
2796+
log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize)
2797+
}
2798+
} else {
2799+
buf.Write([]byte("ZLIB"))
2800+
var sizeBytes [8]byte
2801+
binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
2802+
buf.Write(sizeBytes[:])
2803+
}
27852804

27862805
var relocbuf []byte // temporary buffer for applying relocations
27872806

src/cmd/link/internal/ld/dwarf.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,11 +2227,18 @@ func dwarfcompress(ctxt *Link) {
22272227
newDwarfp = append(newDwarfp, ds)
22282228
Segdwarf.Sections = append(Segdwarf.Sections, ldr.SymSect(s))
22292229
} else {
2230-
compressedSegName := ".zdebug_" + ldr.SymSect(s).Name[len(".debug_"):]
2230+
var compressedSegName string
2231+
if ctxt.IsELF {
2232+
compressedSegName = ldr.SymSect(s).Name
2233+
} else {
2234+
compressedSegName = ".zdebug_" + ldr.SymSect(s).Name[len(".debug_"):]
2235+
}
22312236
sect := addsection(ctxt.loader, ctxt.Arch, &Segdwarf, compressedSegName, 04)
22322237
sect.Align = 1
22332238
sect.Length = uint64(len(z.compressed))
2234-
newSym := ldr.CreateSymForUpdate(compressedSegName, 0)
2239+
sect.Compressed = true
2240+
newSym := ldr.MakeSymbolBuilder(compressedSegName)
2241+
ldr.SetAttrReachable(s, true)
22352242
newSym.SetData(z.compressed)
22362243
newSym.SetSize(int64(len(z.compressed)))
22372244
ldr.SetSymSect(newSym.Sym(), sect)

src/cmd/link/internal/ld/elf.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,9 @@ func elfshbits(linkmode LinkMode, sect *sym.Section) *ElfShdr {
11021102
}
11031103
if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
11041104
sh.Flags = 0
1105+
if sect.Compressed {
1106+
sh.Flags |= uint64(elf.SHF_COMPRESSED)
1107+
}
11051108
}
11061109

11071110
if linkmode != LinkExternal {

src/cmd/link/internal/ld/lib.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,7 @@ func (ctxt *Link) hostlink() {
14771477
argv = append(argv, unusedArguments)
14781478
}
14791479

1480-
const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
1480+
const compressDWARF = "-Wl,--compress-debug-sections=zlib"
14811481
if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
14821482
argv = append(argv, compressDWARF)
14831483
}

src/cmd/link/internal/sym/segment.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,6 @@ type Section struct {
6363
Relcount uint32
6464
Sym LoaderSym // symbol for the section, if any
6565
Index uint16 // each section has a unique index, used internally
66+
67+
Compressed bool
6668
}

src/debug/elf/file.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,11 +1150,37 @@ func (f *File) DWARF() (*dwarf.Data, error) {
11501150
if err != nil && uint64(len(b)) < s.Size {
11511151
return nil, err
11521152
}
1153-
1153+
var (
1154+
dlen uint64
1155+
dbuf []byte
1156+
)
11541157
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
1155-
dlen := binary.BigEndian.Uint64(b[4:12])
1156-
dbuf := make([]byte, dlen)
1157-
r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
1158+
dlen = binary.BigEndian.Uint64(b[4:12])
1159+
s.compressionOffset = 12
1160+
}
1161+
if dlen == 0 && len(b) >= 12 && s.Flags&SHF_COMPRESSED != 0 &&
1162+
s.Flags&SHF_ALLOC == 0 &&
1163+
f.FileHeader.ByteOrder.Uint32(b[:]) == uint32(COMPRESS_ZLIB) {
1164+
s.compressionType = COMPRESS_ZLIB
1165+
switch f.FileHeader.Class {
1166+
case ELFCLASS32:
1167+
// Chdr32.Size offset
1168+
dlen = uint64(f.FileHeader.ByteOrder.Uint32(b[4:]))
1169+
s.compressionOffset = 12
1170+
case ELFCLASS64:
1171+
if len(b) < 24 {
1172+
return nil, errors.New("invalid compress header 64")
1173+
}
1174+
// Chdr64.Size offset
1175+
dlen = f.FileHeader.ByteOrder.Uint64(b[8:])
1176+
s.compressionOffset = 24
1177+
default:
1178+
return nil, fmt.Errorf("unsupported compress header:%s", f.FileHeader.Class)
1179+
}
1180+
}
1181+
if dlen > 0 {
1182+
dbuf = make([]byte, dlen)
1183+
r, err := zlib.NewReader(bytes.NewBuffer(b[s.compressionOffset:]))
11581184
if err != nil {
11591185
return nil, err
11601186
}

0 commit comments

Comments
 (0)