extraexe := extrasize(elfexe)
extrapie := extrasize(elfpie)
+ if sizepie < sizeexe || sizepie-extrapie < sizeexe-extraexe {
+ return
+ }
diffReal := (sizepie - extrapie) - (sizeexe - extraexe)
diffExpected := (textpie + dynpie) - (textexe + dynexe)
}
var buf bytes.Buffer
- buf.Write([]byte("ZLIB"))
- var sizeBytes [8]byte
- binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
- buf.Write(sizeBytes[:])
+ if ctxt.IsELF {
+ switch ctxt.Arch.PtrSize {
+ case 8:
+ binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr64{
+ Type: uint32(elf.COMPRESS_ZLIB),
+ Size: uint64(total),
+ Addralign: uint64(ctxt.Arch.Alignment),
+ })
+ case 4:
+ binary.Write(&buf, ctxt.Arch.ByteOrder, elf.Chdr32{
+ Type: uint32(elf.COMPRESS_ZLIB),
+ Size: uint32(total),
+ Addralign: uint32(ctxt.Arch.Alignment),
+ })
+ default:
+ log.Fatalf("can't compress header size:%d", ctxt.Arch.PtrSize)
+ }
+ } else {
+ buf.Write([]byte("ZLIB"))
+ var sizeBytes [8]byte
+ binary.BigEndian.PutUint64(sizeBytes[:], uint64(total))
+ buf.Write(sizeBytes[:])
+ }
var relocbuf []byte // temporary buffer for applying relocations
newDwarfp = append(newDwarfp, ds)
Segdwarf.Sections = append(Segdwarf.Sections, ldr.SymSect(s))
} else {
- compressedSegName := ".zdebug_" + ldr.SymSect(s).Name[len(".debug_"):]
+ var compressedSegName string
+ if ctxt.IsELF {
+ compressedSegName = ldr.SymSect(s).Name
+ } else {
+ compressedSegName = ".zdebug_" + ldr.SymSect(s).Name[len(".debug_"):]
+ }
sect := addsection(ctxt.loader, ctxt.Arch, &Segdwarf, compressedSegName, 04)
sect.Align = 1
sect.Length = uint64(len(z.compressed))
- newSym := ldr.CreateSymForUpdate(compressedSegName, 0)
+ sect.Compressed = true
+ newSym := ldr.MakeSymbolBuilder(compressedSegName)
+ ldr.SetAttrReachable(s, true)
newSym.SetData(z.compressed)
newSym.SetSize(int64(len(z.compressed)))
ldr.SetSymSect(newSym.Sym(), sect)
}
if strings.HasPrefix(sect.Name, ".debug") || strings.HasPrefix(sect.Name, ".zdebug") {
sh.Flags = 0
+ if sect.Compressed {
+ sh.Flags |= uint64(elf.SHF_COMPRESSED)
+ }
}
if linkmode != LinkExternal {
argv = append(argv, unusedArguments)
}
- const compressDWARF = "-Wl,--compress-debug-sections=zlib-gnu"
+ const compressDWARF = "-Wl,--compress-debug-sections=zlib"
if ctxt.compressDWARF && linkerFlagSupported(ctxt.Arch, argv[0], altLinker, compressDWARF) {
argv = append(argv, compressDWARF)
}
Relcount uint32
Sym LoaderSym // symbol for the section, if any
Index uint16 // each section has a unique index, used internally
+
+ Compressed bool
}
if err != nil && uint64(len(b)) < s.Size {
return nil, err
}
-
+ var (
+ dlen uint64
+ dbuf []byte
+ )
if len(b) >= 12 && string(b[:4]) == "ZLIB" {
- dlen := binary.BigEndian.Uint64(b[4:12])
- dbuf := make([]byte, dlen)
- r, err := zlib.NewReader(bytes.NewBuffer(b[12:]))
+ dlen = binary.BigEndian.Uint64(b[4:12])
+ s.compressionOffset = 12
+ }
+ if dlen == 0 && len(b) >= 12 && s.Flags&SHF_COMPRESSED != 0 &&
+ s.Flags&SHF_ALLOC == 0 &&
+ f.FileHeader.ByteOrder.Uint32(b[:]) == uint32(COMPRESS_ZLIB) {
+ s.compressionType = COMPRESS_ZLIB
+ switch f.FileHeader.Class {
+ case ELFCLASS32:
+ // Chdr32.Size offset
+ dlen = uint64(f.FileHeader.ByteOrder.Uint32(b[4:]))
+ s.compressionOffset = 12
+ case ELFCLASS64:
+ if len(b) < 24 {
+ return nil, errors.New("invalid compress header 64")
+ }
+ // Chdr64.Size offset
+ dlen = f.FileHeader.ByteOrder.Uint64(b[8:])
+ s.compressionOffset = 24
+ default:
+ return nil, fmt.Errorf("unsupported compress header:%s", f.FileHeader.Class)
+ }
+ }
+ if dlen > 0 {
+ dbuf = make([]byte, dlen)
+ r, err := zlib.NewReader(bytes.NewBuffer(b[s.compressionOffset:]))
if err != nil {
return nil, err
}